2009-09-09 51 views
1

我正在更新多个表中的数据。目前我有一个表有一个字段,“来源”,这只是包含字段“itemid”的所有表的列表。我也有一个表,有2个字段,“itemid”和“olditemid”。在TSQL中,我想遍历源代码并快速创建更新语句。这是我正在尝试做的,但我在更新声明中发现我的变量未声明的错误。我不确定这是否接近我应该这样做的正确方式。想法?即时创建SQL UPDATE语句

DECLARE @tblName varchar(50) 

DECLARE process_cursor CURSOR FOR 
    SELECT source 
    FROM tmpTableNames 

OPEN process_cursor 

FETCH NEXT FROM processcursor 
INTO @tblName 

WHILE @@FETCH_STATUS = 0 

    UPDATE @tblName 
     SET itemid = r.itemid 
     FROM @tblName v, itemref r 
     WHERE r.olditemid = v.itemid 

    FETCH NEXT FROM process_cursor 
    INTO @tblName 

END 
CLOSE processcursor 
DEALLOCATE processcursor 
+0

@tblName应该是'sysname'类型,它是对象名称的正确类型和长度。对于某些对象,varchar(50)太短,并且允许表名包含unicode字符。 – 2009-09-09 17:57:26

回答

4

你正在做的事情被称为“动态SQL”。当你走在正确的轨道上时,你不能简单地用变量代替对象名称并执行查询。我会把动态SQL的陷阱留给其他人。什么你要找的是这样的:

DECLARE @tblName varchar(50) 

DECLARE process_cursor CURSOR FOR 
    SELECT source 
    FROM tmpTableNames 

OPEN process_cursor 

FETCH NEXT FROM processcursor 
INTO @tblName 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    DECLARE @sql NVARCHAR(500) 

    SELECT @sql = 'UPDATE [' + @tbleName + '] SET itemid = r.itemid FROM [' + @tbleName + '] v, itemref r WHERE r.ilditemid = v.itemid' 

    EXEC sp_executesql @sql 
    FETCH NEXT FROM process_cursor 
    INTO @tblName 

END 
CLOSE processcursor 
DEALLOCATE processcursor 

这样做是把你的更新查询转换成字符串,然后传递包含在字符串到sp_executesql SQL存储过程(这是执行动态的推荐方法sql,而不是EXEC('foo'))。

+0

您应该始终使用QUOTENAME将表格等对象名称包装到适当的'['和']'括号中。 – 2009-09-09 17:55:54

+0

@Remus:很好。纠正。 – 2009-09-09 17:58:50

0

,您是否试图 DECLARE @tblName VARCHAR(50)? 我会认为这样做。

+0

我确实宣布它最高。 – SDC 2009-09-09 16:18:49

+0

您可能错过了未格式化代码中的声明。 – 2009-09-09 16:19:22

3

我不认为你可以使用这样的变量来做到这一点。您可以使用动态SQL进行更新:

DECLARE @sql VARCHAR(1000) 

SET @sql = 'UPDATE' + @tableName + etc.. 

EXEC (@sql) 

只需在光标内执行此操作即可。

0

我从来没有成功地与基于可变UPDATE语句(即,UPDATE @tblName),除非我拍摄他们进入一个字符串和动态执行这些,如:

EXEC 'UPDATE ' + @tblName + ' 
SET ItemId = (SELECT r.ItemId FROM itemref r WHERE r.OldItemId = ' + @tblName + '.itemId)' 

对于表TheTable,这应该扩展为:

EXEC 'UPDATE TheTable 
     SET ItemId = (SELECT r.ItemId FROM itemref r WHERE r.OldItemId = TheTable.ItemId)' 
1

您不能动态执行sql这样的 - 你需要一个动态生成的字符串传递到执行函数是这样的:

DECLARE @tblName varchar(50) 

DECLARE process_cursor CURSOR FOR 
    SELECT source 
    FROM tmpTableNames 

OPEN process_cursor 

FETCH NEXT FROM processcursor 
INTO @tblName 

WHILE @@FETCH_STATUS = 0 

    Declare @sql varchar(5000) 
    Select @sql = 'UPDATE ' + @tblName + 
     'SET itemid = r.itemid 
     FROM ' + @tblName + ' v, itemref r 
     WHERE r.olditemid = v.itemid' 

    Exec @sql 
    FETCH NEXT FROM process_cursor 
    INTO @tblName 

END 
CLOSE processcursor 
DEALLOCATE processcursor