2

我是 SQLServer 脚本的新手(通常是 C++ 开发人员),非常感谢您的帮助。

我正在尝试对 SQLServer 数据库中包含“PROJID”列的所有表执行“查找和替换”更新。我真的很难找到一种不向我报告的方法:

消息 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”语句之外进行列存在检查,但我也不知道如何去做。

4

2 回答 2

2

您只需要在不同的范围内执行此操作。

IF EXISTS (SELECT 1 FROM sys.columns ...)
BEGIN
  DECLARE @sql NVARCHAR(MAX);
  SET @sql = N'UPDATE ...';
  EXEC sp_executesql @sql;
END
于 2012-09-04T17:01:24.060 回答
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. 您的第一个查询只是说如果表@TableNamePROJID列,则@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
于 2012-09-04T17:22:49.783 回答