Ошибка неверного столбца при использовании Dynami c SQL - PullRequest
0 голосов
/ 03 марта 2020

Я пытаюсь использовать Dynami c SQL в первый раз. Существует два набора SQL для выполнения в зависимости от условий. При попытке выполнить @sql4 часть Else выполняется нормально без ошибок. Однако первая часть SQL выдает ошибку:

недопустимый столбец / Не удалось связать идентификатор из нескольких частей "tp.Acquisition Date"

Dynami c SQL используется в обоих случаях одинаково, и почему-то первая часть выдает ошибку, говорящую, что tp не распознан, что является не чем иным, как псевдонимом для таблицы 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;

1 Ответ

1 голос
/ 03 марта 2020

Я думаю, что вы получили свой ответ от APH в комментариях. И вы получили еще один совет от Луука и Ламу относительно преобразования sp_executesql @sql4 в select @sql4 или print @sql4, копирования результата в редактор и просмотра там сообщения об ошибке.

Но я бы порекомендовал вам встроить ваши вставки в оператор динамического c вне самого оператора:

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

     ';

При таком подходе у вас есть немного больше шансов избежать или перехватить ошибки при написании кода (например, легче увидеть, что во втором запросе отсутствует оператор соединения, который есть в первом). И еще более ясно, какова цель «большой картины» всего вашего запроса.

...