CTE с динамическим запросом - PullRequest
2 голосов
/ 11 марта 2010

У меня есть динамический запрос, который я вызываю, и я помещаю Result в таблицу переменных

INSERT INTO @outTable 

EXEC sp_executesql @query;

Проблема в том, что @outTable должно измениться. При добавлении столбца в @query - @query это еще одна хранимая процедура.

Я пытался использовать CTE (WITH), но он не работает с EXEC.

Можно ли это сделать в T-SQL?

как то так

DECLARE @outTable TABLE (
                            ID int,
                            Record_ID int, 
                            Order_ID nchar(16),
                            ...and around 30 columns
                        );  

    SET @query = N'EXEC [OrderDep].[Order_Find] @FreeWhere =N'' WHERE '+ @Where +'''';

    BEGIN TRY 
        INSERT INTO @outTable 
            EXEC sp_executesql @query;

    END TRY     
    BEGIN CATCH

Ответы [ 4 ]

2 голосов
/ 12 марта 2011

Прочтите это и будьте просветлены.

Вам нужно , чтобы прочитать это, если вы собираетесь использовать динамический SQL:

2 голосов
/ 11 марта 2010

При использовании insert ... exec ... определение таблицы должно соответствовать выходным данным хранимой процедуры.

Поскольку вы создаете оператор @query, вы, вероятно, знаете, что он собирается вернуть.Это может быть много работы, но вам придется скорректировать определение таблицы вручную.

1 голос
/ 11 марта 2010

Учитывая то, что мы знаем о проблеме до сих пор, способ решить эту проблему состоит в том, чтобы либо разветвить логику для использования разных запросов с разными таблицами назначения, либо использовать динамический SQL. Если количество таблиц назначения невелико, то я бы порекомендовал первое решение, которое выглядело бы следующим образом:

If @Parameter = 'SomeValue'
    Insert TableA
    Select ..
    From ...

Else If @Parameter = 'SomeOtherValue'
    Insert TableB
    Select ..
    From 

Я бы не советовал пытаться создать всеобъемлющую функцию, которая может взять любое имя таблицы назначения и текст запроса select и сделать оператор вставки, если это то, чего вы пытаетесь достичь.

0 голосов
/ 11 марта 2011

Это зависит от того, для чего вы хотите эту переменную.

Я подозреваю, однако, что самым простым выходом было бы сохранить данные в сводной форме и оставить их до тех пор, пока они не будут возвращены клиентскому приложению. Затем сохраненный процесс может построить SQL, необходимый для отмены результата.

Сохраните и обработайте что-то вроде этого:

ID       Col         Value
-----------------------------------------------------
1        FName       Dag
1        Email       yeah.right@maybe.no
1        Col3        Value3
...
N        FName       Kristina
N        Email       my.first.love@sadness.info
N        Col3        Value3
N        Col4        Dag hasn't got this attribute

Когда приходит время вернуть данные клиентскому приложению, а не раньше, хранимый процесс может динамически генерировать SQL, чтобы разворачивать данные в следующее:

ID    FName     Email                        Col3      Col4
------------------------------------------------------------------------------------
1     Dag       yeah.right@maybe.no          Value3    (null)
....
N     Kristina  my.first.love@sadness.info   Value3   Dag hasn't got this attribute.

Конечно, набор столбцов будет таким же большим, как набор различных значений Name в сводной таблице данных. Но это хорошо работает, если вы храните много видов объектов в одной таблице, но выбираете только наборы элементов с одинаковыми (или, по крайней мере, похожими) наборами атрибутов. Другое потенциально важное ограничение: ВСЕ будет просто текстом, так что подумайте о последствиях этого.

Однако я думал об использовании этой техники для создания DAL для целей быстрого прототипирования. Очевидно, что это очень дорого по времени и пространству по сравнению с нормализованными таблицами, но позволяет хранить, извлекать и обрабатывать меньшие объемы данных в общем виде.

Чтобы отменить поворот, сгенерируйте SQL с помощью шаблона, подобного следующему:

SELECT 
    ID,
    MAX(CASE WHEN [Name] = 'FName' THEN [Value] END [FName]),
    MAX(CASE WHEN [Name] = 'Email' THEN [Value] END [EMail]),
    ...
FROM 
    Stuff
GROUP BY 
    ID

Пока есть не более одной строки с Name = 'FName', это работает хорошо, так как мы группируем по ID. И генерировать SQL просто; форматирование требуется только для бита CASE:

DECLARE @case varchar(max)
SET @case = 'CASE WHEN [Name] = ''§name'' THEN [Value] END [§name])'

-- Get columns:
SELECT Column_Name INTO #cols FROM INFORMATION_SCHEMA.COLUMNS WHERE Table_Name = @tableName;

-- in loop (can't be bothered to include the code!)
SET @sql = @sql + REPLACE(@case, '§name', @colName)
...
EXEC(@sql)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...