我是SQLServer脚本编程的新手(通常是C ++开发人员),非常感谢您提供一些帮助。
我正在尝试对包含“PROJID”列的SQLServer数据库中的所有表执行“查找和替换”更新。我真的很难找到一种不向我报告的方法:
消息207,级别16,状态1,行1无效的列名称'PROJID'。
我正在执行的声明是:
EXEC
(
'IF EXISTS(SELECT * FROM sys.columns WHERE name = N''PROJID'' AND Object_ID = Object_ID(N''' + @TableName + '''))' +
' BEGIN' +
' UPDATE ' + @TableName +
' SET ' + @ColumnName + ' = REPLACE(' + @ColumnName + ',''' + @ReplaceIDStr + ''',''' + @FindIDStr + ''')' +
' WHERE ' + @ColumnName + ' LIKE ''' + @ReplaceIDStr + '''' + ' AND PROJID = ''1000''' +
' END'
)
我也尝试过使用:
'IF COL_LENGTH(''' + @TableName + ''',''PROJID'') IS NOT NULL' +
而不是上面的列存在检查。这仍然给我“无效的列名称”消息。
我很乐意在'Exec'语句之外进行列存在检查,但我不知道该怎么做。
答案 0 :(得分:2)
你只需要在不同的范围内进行。
IF EXISTS (SELECT 1 FROM sys.columns ...)
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'UPDATE ...';
EXEC sp_executesql @sql;
END
答案 1 :(得分:1)
将此查询的结果输出到文本。不要忘记更改变量的值!取结果并运行它。
SET NOCOUNT ON
DECLARE @ColumnName VARCHAR(200) = 'ReplaceColumn'
, @ReplaceIdStr VARCHAR(200) = 'ExampleReplaceIdStr'
, @FindIdStr VARCHAR(200) = 'ExampleFindIdStr'
PRINT 'BEGIN TRAN'
PRINT 'SET XACT_ABORT ON'
SELECT
'UPDATE ' + C.TABLE_NAME + CHAR(13)
+ 'SET ' + @ColumnName + ' = REPLACE(' + @ColumnName + ', ''' + @ReplaceIdStr + ''', ''' + @FindIdStr + ''')' + CHAR(13)
+ 'WHERE ' + @ColumnName + ' LIKE ''%' + @ReplaceIdStr + '%'' AND PROJID = ''1000''' + CHAR(13)
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.COLUMN_NAME = 'PROJID'
PRINT 'COMMIT TRAN'
SET NOCOUNT OFF
编辑:另外,一些推理:你说你想要更新所有包含名为PROJID
的列的表。您的第一个查询只是表示如果表@TableName
有一个PROJID
列,则会更新@ColumnName
。但它并不能保证它上面有@ColumnName。我给出的查询也没有检查,因为我假设所有PROJID
的表都有@ColumnName
。如果不是这样,请告诉我,我可以更新答案以检查。您收到Invalid Column Name
错误指向@ColumnName
不存在。
您的查询最多会更新一个表(@TableName
),而我给您的那个表将更新每个具有PROJID
的表。我希望这就是你的目标。
编辑2:这是一个可以同时运行它的版本:
DECLARE @ColumnName VARCHAR(200) = 'Value'
, @ReplaceIdStr VARCHAR(200) = 'ExampleReplaceIdStr'
, @FindIdStr VARCHAR(200) = 'ExampleFindIdStr'
DECLARE @Sql NVARCHAR(MAX)
DECLARE UpdateCursor CURSOR FOR
SELECT
'UPDATE ' + C.TABLE_NAME
+ ' SET ' + @ColumnName + ' = REPLACE(' + @ColumnName + ', ''' + @ReplaceIdStr + ''', ''' + @FindIdStr + ''')'
+ ' WHERE ' + @ColumnName + ' LIKE ''%' + @ReplaceIdStr + '%'' AND PROJID = ''1000'''
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.COLUMN_NAME = 'PROJID'
OPEN UpdateCursor
FETCH NEXT FROM UpdateCursor
INTO @Sql
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC sp_executesql @Sql
FETCH NEXT FROM UpdateCursor
INTO @Sql
END
CLOSE UpdateCursor
DEALLOCATE UpdateCursor