动态创建 SQL UPDATE 语句

发布于 2024-08-04 02:57:23 字数 643 浏览 9 评论 0原文

我正在更新多个表中的数据。目前我有一个表,其中有一个字段“sources”,它只是包含字段“itemid”的所有表的列表。我还有一个包含 2 个字段的表,“itemid”和“olditemid”。在 TSQL 中,我想迭代源并动态创建更新语句。这是我试图做的,但我在更新语句中收到一些错误,表明我的变量未声明。我不确定这是否接近我应该这样做的正确方式。有想法吗?

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

I am in the midst of updating data in multiple tables. Currently I have a table that has one field, "sources", that is just a list of all tables that include the field "itemid". I also have a table that has 2 fields, "itemid" and "olditemid". In TSQL, I would like to iterate through the sources and create the update statements on the fly. Here is what I was trying to do but I get some errors in the update statement that my variable is not declared. I am not sure this is even close the correct way I should be doing this. Ideas?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

凯凯我们等你回来 2024-08-11 02:57:23

您尝试执行的操作称为“动态 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

它的作用是将更新查询转换为字符串,然后将该字符串中包含的 SQL 传递给 sp_executesql 存储过程(这是执行动态的推荐方法) sql,而不是 EXEC('foo'))。

What you are trying to do is referred to as "dynamic SQL". While you're on the right track, you can't simply stick a variable in place of an object name and execute the query. I'll leave the pitfalls of dynamic SQL to someone else. What you're looking for is this:

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

What this does is turn your update query into a string, then passes the SQL contained in that string to the sp_executesql stored procedure (this is the recommended way of executing dynamic sql, rather than EXEC('foo')).

望笑 2024-08-11 02:57:23

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

DECLARE @sql VARCHAR(1000)

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

EXEC ( @sql )

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

I don't think you can do it using a variable like that. You could use dynamic SQL for the update:

DECLARE @sql VARCHAR(1000)

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

EXEC ( @sql )

And just do this inside your cursor.

温馨耳语 2024-08-11 02:57:23

您不能像这样动态执行 sql - 您需要将动态生成的字符串传递到 exec 函数中,如下所示:

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

You can't execute sql dynamically like this - you need to pass a dynamically generated string into the exec function like this:

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
萌化 2024-08-11 02:57:23

你试过吗
声明 @tblName varchar(50)?
我想这样就可以了。

did you try
DECLARE @tblName varchar(50)?
I would think that would do it.

心房的律动 2024-08-11 02:57:23

我从未成功使用基于变量的 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)'

I've never been successful with variable-based UPDATE statements (i.e., UPDATE @tblName), unless I captured them into a string and executed these dynamically, as in:

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

For table TheTable, this should expand to:

EXEC 'UPDATE TheTable
      SET ItemId = (SELECT r.ItemId FROM itemref r WHERE r.OldItemId = TheTable.ItemId)'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文