简体   繁体   中英

Invalid Column Error while using dynamic SQL

I am attempting to use dynamic SQL for the first time. There are two sets of SQL to execute based on conditions. When trying to Execute @sql4 the Else part executes fine with no errors. However the first part of SQL throws an error:

invalid column/The multi-part identifier "tp.Acquisition Date" could not be bound

The dynamic SQL used in both cases is the same and somehow the first part throws an error saying tp is not recognized which is the nothing but an alias name for Temp.property table.

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;

I think you got your answer by APH in the comments. And you got further advice by Luuk and Lamu with respect to converting sp_executesql @sql4 to select @sql4 or print @sql4 , copying the result into an editor, and reviewing the error message there.

But I would further recommend that you build your inserts into the dynamic statement outside of the statement itself:

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'');

Also note that I wrapped any column_name in brackets, which may resolve another problem, given that 'Acquisition Date' has a space in the name.

Then insert them as variables:

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

     ';

With this approach, you have a little more chance of avoiding or catching errors as you write the code (for instance, it is easier to see that the second query is missing a join statement that the first has). And it is more clear what the 'big picture' intent is of your entire query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM