Reputation: 957
I am writing a stored proc that needs to search a database for all tables that have a certain column name. Once I get a list of tables that have that column I need to update a value in that column. So first I get a list of tables that have a certain column.
SELECT c.name AS 'ColumnName'
,t.name AS 'TableName'
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE 'company'
ORDER BY TableName
Now that I have a list of tables that need to be updated I need to run a query similar to the following to update the data in each table.
update table1 set company = @newValue where company = @oldvalue
I'm not sure how to go about writing this part. My first thought was to write a dynamic update statement inside of a cursor like:
Declare @newValue
Declare @oldValue
SET @companyCursor = CURSOR FOR
SELECT t.name AS 'TableName'
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE 'company'
OPEN @companyCursor;
FETCH NEXT FROM @companyCursor INTO @tableName;
WHILE @@FETCH_STATUS = 0
BEGIN
update @tableName set company = @newValue where company = @oldValue
FETCH NEXT FROM @companyCursor INTO INTO @tableName;
END
Is this a good strategy?
Upvotes: 1
Views: 2658
Reputation: 33581
I really dislike cursors so even in cases like this where a cursor is a viable solution I like to leverage the system views to avoid looping. You still have to use dynamic sql because object names cannot be parameterized.
Please note that I am guessing the datatype for company here and you can change this easily. Make sure you change the variable definition both in your script AND in the dynamic sql. You entire script could be shortened to something like this.
declare @SQL nvarchar(max) = ''
, @newValue varchar(10) = 'new'
, @oldValue varchar(10) = 'old'
select @SQL = @SQL + 'Update ' + quotename(object_name(c.object_id)) + ' set company = @newValue where company = @oldValue;'
from sys.columns c
where c.name = 'company'
select @SQL
--uncomment the line below when you are satisfied the dynamic sql is correct.
--This dynamic sql is parameterized as much as possible
--exec sp_executesql @SQL, N'@newValue varchar(10), @oldValue varchar(10)', @newValue = @newValue, @oldValue = @oldValue
Upvotes: 2
Reputation: 5458
No the update at the end will not work. You need to use exec (@sql) like this:
declare @sql varchar(4000)
begin
set @sql = 'update ' + @tableName + 'set company = ' + @newValue + 'where company = ' + @oldValue
exec (@sql)
fetch next ...
end
This assumes that @newvalue and @oldvalue are being assigned values somewhere.
Upvotes: 1