【发布时间】:2015-09-10 12:52:14
【问题描述】:
我正在与一位客户合作,他以某种方式将小写项目编号加载到一系列 SQL 表中。这在这个特定的应用程序中是不可能的,并且会导致各种问题。我打算一次将这些项目更新为大写版本,但很快意识到这将花费很长时间。所以我做了一件不可思议的事,并试图用光标来帮助我,但是我一直被一个让我困惑的错误绊倒。这是我的代码:
declare @tablename varchar(10)
declare upper_case cursor for
SELECT sys.objects.NAME
FROM sys.columns
INNER JOIN sys.objects ON sys.columns.object_id = sys.objects.object_id
WHERE sys.columns.NAME = 'item'
AND sys.objects.type = 'U'
OPEN upper_case
FETCH NEXT FROM upper_case into @tablename
UPDATE @tablename
SET item = upper(item)
CLOSE upper_case
DEALLOCATE upper_case
这是错误:
消息 1087,第 16 级,状态 1,第 13 行
必须声明表变量“@tablename”。
我没有将@tablename 用作表变量,而是尝试将其用作标量变量,但我想,到底怎么回事,我会咬一口的。所以我把它切换到一个表变量:
declare @tablename table (tablename varchar(10))
然后我得到这个错误:
消息 137,第 16 级,状态 1,第 5 行
必须声明标量变量“@tablename”。
我错过了什么?我是否不允许在UPDATE 语句中使用变量?我知道每个UPDATE 只能更新一个表,但我认为通过使用游标,我实际上是在发出多个更新,每个更新只更新一个表。我误会了吗?
这是有效的结果。我不敢相信我是第一个想要这样做的人,我怀疑我会是最后一个:
DECLARE @tablename varchar(10)
DECLARE @sql nvarchar(max)
declare upper_case cursor for
SELECT sys.objects.NAME
FROM sys.columns
INNER JOIN sys.objects ON sys.columns.object_id = sys.objects.object_id
WHERE sys.columns.NAME = 'item'
AND sys.objects.type = 'U'
OPEN upper_case
FETCH upper_case into @tablename
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = 'UPDATE [' + @tablename + '] SET item = upper(item)'
EXEC(@sql)
FETCH upper_case into @tablename
END
CLOSE upper_case
DEALLOCATE upper_case
【问题讨论】:
-
您缺少动态 SQL,快速解决方法
EXEC('UPDATE ' + @tablename + ' SET item = upper(item))'
标签: sql-server tsql cursor sql-update