【问题标题】:SQL Iterate Over All TablesSQL 遍历所有表
【发布时间】:2014-10-22 18:47:58
【问题描述】:

我正在运行以下代码以从具有特定列的所有表中提取所有相关行。外部IF 应该检查该列是否存在于该迭代的表中。如果不是,它应该完成该迭代并移动到下一个表。如果表有GCRecord 列,那么它应该检查该表是否会返回任何记录。如果没有要返回的记录,它应该结束该迭代并移动到下一个表。如果有记录,应该在SSMS中显示。

USE WS_Live

EXECUTE sp_MSforeachtable 
'
    USE WS_Live

    IF EXISTS(  SELECT * 
                FROM sys.columns
                WHERE columns.Object_ID = Object_ID(''?'')
                AND Name = ''GCRecord''
             ) 
    BEGIN
        IF EXISTS (SELECT * FROM ? WHERE GCRecord IS NOT NULL)

        BEGIN
            SELECT * FROM ? WHERE GCRecord IS NOT NULL
        END
    END
'

这似乎有效,因为 SSMS 只返回具有有效条目的网格。我不明白的是:为什么我仍然收到这些错误?

Msg 207, Level 16, State 1, Line 10
Invalid column name 'GCRecord'.
Msg 207, Level 16, State 1, Line 13
Invalid column name 'GCRecord'.

编辑

使用建议后,我有这个:

USE WS_Live

EXECUTE sp_MSforeachtable 
'
    USE WS_Live

    IF EXISTS(SELECT * FROM sys.columns WHERE columns.Object_ID = Object_ID(''?'')AND Name = ''GCRecord'') 

    BEGIN
    IF EXISTS (SELECT * FROM ? WHERE GCRecord IS NOT NULL)

            BEGIN
               EXEC('' SELECT * FROM ? WHERE GCRecord IS NOT NULL'')
            END
    END
'

返回此错误:

Msg 207, Level 16, State 1, Line 7
Invalid column name 'GCRecord'.

指的是这一行

IF EXISTS(SELECT * FROM sys.columns WHERE columns.Object_ID = Object_ID(''?'')AND Name = ''GCRecord'') 

更新

我尝试嵌套 EXEC 语句不起作用,但使用选定的答案我得到了我正在寻找的结果而没有错误。

【问题讨论】:

  • 我的猜测是 SSMS 仍在编译内部查询,即使它不会执行基于EXISTS结果。
  • 你可能会看看答案here是否有帮助。

标签: sql sql-server conditional sp-msforeachdb


【解决方案1】:

在开始时使用动态查询避免内部预编译代码,因为表不包含列'GCRecord'

USE WS_Live
GO

EXECUTE sp_MSforeachtable 
'
    IF EXISTS(  SELECT * 
                FROM sys.columns
                WHERE columns.Object_ID = Object_ID(''?'')
                AND Name = ''GCRecord''
             ) 
    BEGIN

          EXEC(''          
                  IF EXISTS (SELECT * FROM ? WHERE GCRecord IS NOT NULL)
                 BEGIN
                         SELECT * FROM ? WHERE GCRecord IS NOT NULL
                 END
              '')
    END
'

【讨论】:

    【解决方案2】:

    你很亲密。使用“执行”

    USE WS_Live 
    
    EXECUTE sp_MSforeachtable  
    ' 
        USE WS_Live 
    
        IF EXISTS(  SELECT *  
                    FROM sys.columns 
                    WHERE columns.Object_ID = Object_ID(''?'') 
                    AND Name = ''GCRecord''
                 ) 
        BEGIN
            EXEC(''SELECT * FROM ? WHERE GCRecord IS NOT NULL'')
        END
    '
    

    【讨论】:

    • 谢谢。这让我很接近。我添加了一个更新。
    • 知道了。感谢您的回答,我尝试嵌套 EXEC() 语句,这显然不起作用。我按照@AA.SC 所示移动了它们,并且我摆脱了所有错误。
    【解决方案3】:

    请试试这个动态 sql。当你准备好运行时,从exec 中删除评论

    declare @t varchar(max) = ''
    
    SELECT @t =  @t + 'SELECT * FROM ' + a.name + ' WHERE GCRecord IS NOT NULL;' + char(13)
                    FROM sys.columns b join sys.objects a  on
                     b.Object_ID = a.Object_ID
                    WHERE b.Name ='CreateDt'
    
    Print  @t
    --exec (@t)
    

    【讨论】:

      【解决方案4】:

      使用@whereand 来简化:

      exec sp_MSforeachtable 
      @command1='select * from ? where GCRecord is not null', 
      @whereand='and exists(select 1 from sys.columns c where c.object_id = o.id 
                            and c.name = ''GCRecord'')' 
      

      【讨论】:

        猜你喜欢
        • 2015-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-09
        • 2012-09-17
        • 2011-01-28
        • 1970-01-01
        相关资源
        最近更新 更多