I'm working with a customer who somehow loaded lowercase item numbers into a series of SQL tables. This should not be possible in this particular application and is causing all sorts of issues. I set out to update the items to the upper case versions one at a time but quickly realized that this would take forever. So I did the unthinkable and tried to use a cursor to help me out, however I keep stumbling over an error that has me baffled. Here's my code:
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
And here's the error:
Msg 1087, Level 16, State 1, Line 13
Must declare the table variable "@tablename".
I'm not using @tablename
as a table variable, I'm trying to use it as a scalar variable but I thought, what the heck, I'll bite. So I switched it to a table variable:
declare @tablename table (tablename varchar(10))
And then I get this error:
Msg 137, Level 16, State 1, Line 5
Must declare the scalar variable "@tablename".
What am I missing? Am I not allowed to use a variable in an UPDATE
statement? I know that each UPDATE
can only update one table, but I thought that by using the cursor, I was effectively issuing multiple updates, each which only updates one table. Did I misunderstand that?
Here's the result that worked. I can't believe I'm the first to want to do this and I doubt I'll be the last:
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