T-SQL中的游标不起作用

时间:2017-06-08 12:34:06

标签: sql-server database tsql ssms-2014

我正在使用游标将数据从一个表(Family_tree)随机复制到另外两个表(Family_tree1 + @time,Family_tree2 + @time)。代码执行成功,但没有更新行。实际上是从表中复制的内容。 我正在使用Microsoft SQL Server Management Studio。这是带有光标的脚本部分:

---creating two tables beforehand
DECLARE @random int
DECLARE 
@first_name nvarchar(20),
@last_name AS nvarchar(20),
@date_of_birth AS nchar(10),
@date_of_death AS nchar(10),
@place_of_death AS nvarchar(30),
@credit_card AS nchar(16),
@ID_member AS int,
@FK_gender AS nchar(3), 

DECLARE curs CURSOR FOR SELECT first_name, last_name, date_of_birth, date_of_death, place_of_death, credit_card, ID_member, FK_gender,  FROM Family_tree
OPEN curs

FETCH NEXT FROM curs INTO  @first_name, @last_name, @date_of_birth, @date_of_death, @place_of_death, @credit_card, @ID_member, @FK_gender, 
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @random = RAND() * 1000000
    IF @random % 2 = 1
    BEGIN 
        SET @sqlString = 'INSERT INTO [Family_tree1' + @time +  ']  (first_name, last_name, date_of_birth, date_of_death, place_of_death,  credit_card, ID_member, FK_gender) 
    VALUES (' 
     + @first_name  + ','  + @last_name  + ',' + @date_of_birth + ',' + @date_of_death + ',' + @place_of_death + ',' + @credit_card + ',' 
     + CAST(@ID_member AS nvarchar)  +','+ @FK_gender  + ')'
    END
    ELSE
    BEGIN
    SET @sqlString = 'INSERT INTO [Family_tree2' + @time +  '] (first_name, last_name, date_of_birth, date_of_death, place_of_death, credit_card, ID_member, FK_gender) 
    VALUES (' + @first_name  + ','  + @last_name  + ',' + @date_of_birth + ',' + @date_of_death + ',' + @place_of_death + ',' + @credit_card + ',' 
     + CAST(@ID_member AS nvarchar)  +','+ @FK_gender + ')'
END
EXECUTE(@sqlString)
FETCH NEXT FROM curs INTO  @first_name, @last_name, @date_of_birth, @date_of_death, @place_of_death, @credit_card, @ID_member, @FK_gender
END
CLOSE curs
DEALLOCATE curs
END;    

我是T-SQL的新手,非常感谢您的建议! 提前谢谢(:

1 个答案:

答案 0 :(得分:1)

如果你"有"要在游标中执行此操作,则需要注意空值。您还需要注意您使用字符串的事实,当插入VALUES子句时,这些字符串应引用

而不是

VALUES (' + @first_name  + ',

您需要以下内容:

VALUES (' + COALESCE('''' + REPLACE(@first_name,'''','''''') + '''','NULL')  + ',

等等你的其他价值观。这将使用双引号替换值中的任何单引号,然后将整个字符串包装在单引号中。 NULL经过所有处理后仍然存在,因此我们还使用COALESCENULL替换为最终字符串 1 中的NULL字面值

在愤怒地运行光标之前,我建议您在一行中执行此操作并打印字符串而不是执行它,以检查它是否正常"。

我还建议您考虑使用更好的数据类型 - 出生/死亡日期会更好地作为实际date值而不是字符串来处理。

1 Guido在评论中提出了ISNULL,这与COALESCE类似,但有一些奇怪的限制,我通常建议不要使用。他们还建议替换应该是一个空字符串,但是这会导致VALUES(... ,, ...)位于NULL值的位置,这会产生错误。