T SQL: работает exe c после INSERT - PullRequest
0 голосов
/ 16 апреля 2020

Мне нужно конвертировать старые данные из нескольких таблиц. Я только сейчас узнал, после написания хранимой процедуры, которая делает это для одной таблицы, что она также должна обрабатывать данные из пары других таблиц. Это означает, что моя процедура должна быть изменена, чтобы правильно справиться с этим. Я хотел бы делать это динамически, не вдаваясь в показатели производительности. Я узнал об использовании exe c sp_execute sql @SQLStatement, чтобы избежать проблем с производительностью динамического c SQL.

Однако, если я напишу ниже, я не получу результатов:

SET @SQLStatement = 'select CONVERT(XML, ' + @ConvColumn + ') ' + @AdditionalColumns + ' from ' + @ConvTable
INSERT INTO @TempDataConv
exec sp_executesql @SQLStatement

Тем не менее, если я напишу это явно, определяя таблицу и столбцы, это прекрасно работает:

INSERT INTO @TempDataConv
SELECT
    DecPageID,
    PolicyID,
    PolicyNumber,
    CONVERT(XML, DecInfo),
    null
FROM [InternalPortal].[dbo].Decpages

Что может происходить? Поскольку никаких результатов не возвращается, я не уверен, как выяснить проблему. Я предполагаю, что, возможно, я не могу сделать ниже. Это правда? Стоит ли просто записать это в блоки if для разных таблиц?

 INSERT INTO @TempDataConv
exec sp_executesql @SQLStatement

1 Ответ

2 голосов
/ 16 апреля 2020

Я подозреваю, что вы получите более похожую производительность, если вы выполните INSERT в динамическом операторе c, не используя INSERT INTO...EXEC.... Это может привести к чему-то вроде этого:

DECLARE @ConvColumn sysname,
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10);
DECLARE @AdditionalColumns table (Position int,ColumnName sysname);

SET @ConvColumn = N'DecInfo';

INSERT INTO @AdditionalColumns
VALUES(1,N'DecPageID'),
      (2,N'PolicyID'),
      (3,N'PolicyNumber');

DECLARE @SQL nvarchar(MAX);

SET @SQL = N'INSERT INTO dbo.YourTable ({ColumnsList})' + @CRLF +
           N'SELECT CONVERT(xml, ' + QUOTENAME(@ConvColumn) + N'),' + @CRLF +
           STUFF((SELECT N',' + @CRLF +
                         N'       ' + QUOTENAME(ColumnName)
                  FROM @AdditionalColumns
                  ORDER BY Position ASC
                  FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,3,N'') + @CRLF +
          N'FROM [InternalPortal].[dbo].Decpages;';

--PRINT @SQL; --Your debugging best friend

EXEC sys.sp_executesql @SQL;

Одно предостережение: вы не сможете использовать переменную таблицы для INSERT, однако вы можете создать временную таблицу вне области действия динамическое выражение c и INSERT в этом.

Обратите также внимание, что я делаю это безопасным с помощью QUOTENAME. Вот почему я использую переменную таблицы для хранения имен столбцов, так как вы никогда не сможете достичь этого с помощью списка с разделителями (и это действительно оставит широко открытыми ворота впрыска). Вам также необходимо заменить {ColumnsList} фактическими столбцами, которые будут вставлены.

...