如果列存在,则在“EXEC”内执行SQLServer条件

时间:2012-09-04 16:56:43

标签: sql-server exec

我是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'语句之外进行列存在检查,但我不知道该怎么做。

2 个答案:

答案 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