在sql server 2008中循环遍历多个表时出错

时间:2016-06-15 14:48:52

标签: sql sql-server

我有这段代码(sql server 2008)

EXEC sp_MSforeachtable

'
IF ''?'' LIKE ''%_records%''
BEGIN

Update ? set Status = ''expired'' where expire_date_time <= getdate()
END'

当我执行此查询时,它会更新表,但会显示如下错误:

Msg 207, Level 16, State 1, Line 6
Invalid column name 'expire_date_time'.
Msg 207, Level 16, State 1, Line 6
Invalid column name 'expire_date_time'.
Msg 207, Level 16, State 1, Line 6
Invalid column name 'expire_date_time'.
Msg 207, Level 16, State 1, Line 6
Invalid column name 'expire_date_time'.
Msg 207, Level 16, State 1, Line 6
Invalid column name 'expire_date_time'.
Msg 207, Level 16, State 1, Line 6
Invalid column name 'expire_date_time'.

为什么会这样?有人可以用正确的代码指导我吗?我希望将代码放在事件中是可能的,因此它会在特定时间间隔后检查条件。

3 个答案:

答案 0 :(得分:0)

使用TRY / CATCH和RAISE(或THROW)捕获包含表名(?)的自定义错误消息,然后您将知道哪个表缺少该列。

答案 1 :(得分:0)

问题是IF语句不会阻止SQL Server解析命令。例如,尝试:

IF 1=0
BEGIN
    SELECT blah FROM INFORMATION_SCHEMA.TABLES
END

您仍然会收到错误。

此外,拥有像jason_records这样的表是一个非常可怕的想法。

另一种可以实现此目的的方法是仅在动态代码中执行UPDATE

DECLARE
    @table_name    SYSNAME,
    @table_schema  SYSNAME,
    @sql           NVARCHAR(MAX)

DECLARE CURSOR tables_cursor FOR
SELECT TABLE_SCHEMA, TABLE_NAME
FROM
    INFORMATION_SCHEMA.TABLES T
INNER JOIN INFORMATION_SCHEMA.COLUMNS C ON
    C.TABLE_CATALOG = T.TABLE_CATALOG AND
    C.TABLE_SCHEMA = T.TABLE_SCHEMA AND
    C.TABLE_NAME = T.TABLE_NAME AND
    C.COLUMN_NAME = 'expire_date_time'
WHERE
    T.TABLE_NAME LIKE '%_records'

OPEN tables_cursor

FETCH NEXT FROM tables_cursor INTO @table_schema, @table_name

WHILE (@@FETCH_STATUS = 0)
BEGIN
    SELECT @sql = 'UPDATE ' + QUOTENAME(@table_schema) + '.' + QUOTENAME(@table_name) + ' SET status = 'expired' WHERE expire_date_time <= GETDATE()'

    EXEC (@sql)

    FETCH NEXT FROM tables_cursor INTO @table_schema, @table_name
END

CLOSE tables_cursor

DEALLOCATE tables_cursor

答案 2 :(得分:0)

不幸的是,sp_MSforeachtable是不受支持的代码。它可能包含永远不会被纠正的错误。试试[]

...
update ? set [Status] = ''expired'' where [expire_date_time] <= getdate()
...