sql-server - 了解游标的工作原理

标签 sql-server tsql

尝试更改一些存储过程和查询以获得更好的性能。对于某些部分,它正在重写游标语法。为此,我必须充分了解它们的工作原理。我尝试了这个简单的 ETL 示例,但它没有给我预期的结果。基本上,在此处使用光标执行 UPSERT。

示例代码:

CREATE TABLE #Destination 
(PersonID INT, FirstName VARCHAR(10), LastName VARCHAR (10))
 INSERT INTO #Destination VALUES (101, 'M', 'Donalds')
 INSERT INTO #Destination VALUES (102, NULL, 'Richards')
 INSERT INTO #Destination VALUES (103, 'Rianna', 'Lock')
 INSERT INTO #Destination VALUES (104, 'Leo', 'Svensson')

 CREATE TABLE #SourceTable 
 (PersonID INT, FirstName VARCHAR(10), LastName VARCHAR (10))
 INSERT INTO #Destination VALUES (102, 'Diana', 'Richards')
 INSERT INTO #SourceTable VALUES (103, 'Rianna', 'Locks')
 INSERT INTO #SourceTable VALUES (106, 'Cleo', 'Davung')

  DECLARE @PersonID INT
  DECLARE @Firstname VARCHAR (10)
  DECLARE @Lastname VARCHAR (10)

  DECLARE SimpleCursor CURSOR FOR 
  SELECT PersonID, FirstName, LastName 
  FROM #SourceTable

  Open SimpleCursor
  FETCH NEXT FROM SimpleCursor INTO @PersonID, @Firstname, @Lastname
  WHILE @@FETCH_STATUS = 0 
  BEGIN
  IF EXISTS ( SELECT PersonID FROM #Destination
              WHERE PersonID = @PersonID )
    UPDATE #Destination  
    SET #Destination.FirstName = #SourceTable.FirstName,
        #Destination.LastName = #SourceTable.LastName
    FROM #SourceTable
    WHERE #Destination.PersonID = #SourceTable.PersonID
  ELSE
    INSERT INTO #Destination
    SELECT PersonID, Firstname, Lastname FROM #SourceTable

  FETCH NEXT FROM SimpleCursor INTO @PersonID, @Firstname, @Lastname
  END

  CLOSE SimpleCursor
  DEALLOCATE SimpleCursor

SELECT * FROM #Destination

我在这里错过了什么?我没有更新任何东西,而 PersonID 102 和 103 确实存在。

非常感谢。

最佳答案

您没有在 UPDATEINSERT 语句中使用将值提取到其中的变量。尝试:

...
IF EXISTS (SELECT *
                  FROM #Destination
                  WHERE PersonID = @PersonID)
BEGIN
  UPDATE #Destination
         SET FirstName = @FirstName,
             LastName = @LastName
         WHERE PersonID = @PersonID;
END
ELSE
BEGIN
  INSERT INTO #Destination
              (PersonID,
               FirstName,
               LastName)
              VALUES (@PersonID,
                      @FirstName,
                      @LastName);
END;
...

关于sql-server - 了解游标的工作原理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51485438/

相关文章:

SQL Server 模数运算符可跳至大型表中的每第 n 行

mysql - 如何使用 SQL 执行可选 JOIN

sql-server - 使用 "USE"关键字 Vs. T-SQL 中的完整表名

sql-server - 在 SQL Server Management Studio 中,我可以跨多个数据库搜索 Assets 吗?

sql-server - .Net Core Linux 容器不会使用 SQL 身份验证连接到 SQL Server

sql - 使用标识而不是顺序时的随机数

sql - 使用 group by 进行复杂 SQL 连接

tsql - 我可以运行以查看表中是否有任何行的最便宜的查询是什么?

sql-server - SQL Server Float 数据类型计算 vs decimal

sql-server - 无法借助代码创建外键