【问题标题】:Invalid Column Error while using dynamic SQL使用动态 SQL 时出现无效列错误
【发布时间】:2020-06-16 03:56:40
【问题描述】:

我第一次尝试使用动态 SQL。根据条件执行两组 SQL。尝试执行@sql4 时,Else 部分执行良好,没有错误。但是 SQL 的第一部分抛出了一个错误:

无效列/无法绑定多部分标识符“tp.Acquisition Date”

在这两种情况下使用的动态 SQL 是相同的,并且不知何故第一部分会抛出一个错误,说 tp is not Recognized 这只是 Temp.property 表的别名。

Declare @SQL4 NVARCHAR(MAX)
SELECT @sql4=

     'CREATE TABLE dbo.DIM_PROPERTY (' + Stuff(
      (SELECT N', ' + Concat(Column_Name, ' ', ColDT) FROM #TempProp  
       FOR XML PATH(''),TYPE)
      .value('text()[1]','nvarchar(max)'),1,2,N'') + ');' 
        +
        'IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = ''TEMP''
                 AND  TABLE_NAME = ''PROPERTY''))
      BEGIN ' +
      'INSERT INTO dbo.DIM_PROPERTY  ('+ Stuff((SELECT N', ' + Column_Name FROM #TempProp 
        FOR XML PATH(''),TYPE)
      .value('text()[1]','nvarchar(max)'),1,2,N'') + ') ' +'Select ' + Stuff(
      (SELECT N', ' + Concat(TblAlias,Column_Name)  FROM #TempProp
      FOR XML PATH(''),TYPE)
      .value('text()[1]','nvarchar(max)'),1,2,N'') +
    ' from (select imp.PROPERTY_MINI.propertyID as PropertyKey,* from imp.PROPERTY_MINI) mp
    join Temp.PROPERTY tp on tp.PropertyKey = mp.PropertyID
    left join imp.PROPERTY_PHOTO_VIEWER pv
    ON mp.PropertyID = pv.PropertyID


        END

        ELSE 
        BEGIN
        INSERT INTO dbo.DIM_PROPERTY  ('+ Stuff((SELECT N', ' + Column_Name FROM #TempProp 
        FOR XML PATH(''),TYPE)
      .value('text()[1]','nvarchar(max)'),1,2,N'') + ') ' +'Select ' + Stuff(
      (SELECT N', ' + Concat(TblAlias,Column_Name)  FROM #TempProp
      FOR XML PATH(''),TYPE)
      .value('text()[1]','nvarchar(max)'),1,2,N'') +
    ' from (select imp.PROPERTY_MINI.propertyID as PropertyKey,* from imp.PROPERTY_MINI) mp
    left join imp.PROPERTY_PHOTO_VIEWER pv
    ON mp.PropertyID = pv.PropertyID
    END'
        exec sp_executesql @SQL4;

【问题讨论】:

  • 嗨 Priya - 欢迎来到 Stack Overflow。通过添加minimal reproducible example,您可能会为这个问题吸引更好的答案。
  • 当然,添加了 sql 以更详细地显示错误。请查看并发表评论。
  • exec sp_executesql @SQL4; 替换为select @SQL4。这样你就可以检查你的 SQL 语句了。
  • 看起来当您达到else 条件时,您只有两个表,别名为mppv。这就是为什么您在尝试从该部分中别名为 tp 的表格中进行选择时遇到错误的原因。
  • 我建议PRINTing 或SELECTing 你的动态语句的值并调试它;然后将该修复传播到创建它的 SQL。我还建议使用QUOTENAME 正确引用您的动态对象名称。

标签: sql sql-server dynamic


【解决方案1】:

我认为您在 cmets 中通过 APH 得到了答案。 Luuk 和 Lamu 提供了关于将 sp_executesql @sql4 转换为 select @sql4print @sql4、将结果复制到编辑器并在那里查看错误消息的进一步建议。

但我会进一步建议您将插入构建到语句本身之外的动态语句中:

declare 

    @col_types nvarchar(max) = 
        Stuff((
            SELECT N', ' + Concat('[' + Column_Name + ']', ' ', ColDT) 
            FROM #TempProp  
            FOR XML PATH(''),TYPE
        ).value('text()[1]','nvarchar(max)'),1,2,N''),

    @cols nvarchar(max) = 
        Stuff((
            SELECT N', ' + '[' + Column_Name + ']'
            FROM #TempProp 
            FOR XML PATH(''),TYPE
        ).value('text()[1]','nvarchar(max)'),1,2,N''),

    @col_aliases nvarchar(max) =  
        Stuff((
            SELECT N', ' + Concat(TblAlias,'[' + Column_Name + ']')  
            FROM #TempProp
            FOR XML PATH(''),TYPE
        ).value('text()[1]','nvarchar(max)'),1,2,N'');

另请注意,我将任何 column_name 括在括号中,这可能会解决另一个问题,因为“收购日期”的名称中有一个空格。

然后将它们作为变量插入:

declare @SQL4 NVARCHAR(MAX) = '

    CREATE TABLE dbo.DIM_PROPERTY (' +  @col_types + ');

      IF (EXISTS (
          SELECT * FROM INFORMATION_SCHEMA.TABLES 
          WHERE TABLE_SCHEMA = ''TEMP''
          AND  TABLE_NAME = ''PROPERTY''
      ))
      BEGIN 

          INSERT INTO dbo.DIM_PROPERTY  (' + @cols + ')

          Select ' + @col_aliases + ' 
          from (select imp.PROPERTY_MINI.propertyID as PropertyKey,* from imp.PROPERTY_MINI) mp
          join Temp.PROPERTY tp on tp.PropertyKey = mp.PropertyID
          left join imp.PROPERTY_PHOTO_VIEWER pv ON mp.PropertyID = pv.PropertyID

      END
      ELSE 
      BEGIN

          INSERT INTO dbo.DIM_PROPERTY  (' + @cols + ') 
          Select ' + @col_aliases + ' 
          from (select imp.PROPERTY_MINI.propertyID as PropertyKey,* from imp.PROPERTY_MINI) mp
          left join imp.PROPERTY_PHOTO_VIEWER pv ON mp.PropertyID = pv.PropertyID

      END

     ';

使用这种方法,您在编写代码时有更多机会避免或捕获错误(例如,更容易看到第二个查询缺少第一个查询的连接语句)。更清楚的是,您的整个查询的“全局”意图是什么。

【讨论】:

    猜你喜欢
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    相关资源
    最近更新 更多