CTE具有动态查询功能

时间:2010-03-11 15:28:50

标签: sql-server tsql

我有一个动态查询,我调用它并将结果集放在变量表

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 个答案:

答案 0 :(得分:2)

使用insert ... exec ...时,表定义必须与存储过程的输出匹配。

由于您正在创建@query语句,因此您可能知道它将返回什么。这可能需要做很多工作,但您必须手动调整表格定义。

答案 1 :(得分:2)

Read this and be enlightened.

如果你要抛出动态SQL,你需要来阅读这个:

答案 2 :(得分:1)

鉴于我们目前对该问题的了解,解决此问题的方法是将逻辑分叉以使用具有不同目标表的不同查询或使用动态SQL。如果目标表的数量很小,那么我建议使用前面的解决方案:

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

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

我建议不要尝试创建一个包含任何目标表名称和select查询文本的全包函数,如果这是您要实现的目的,请创建一个insert语句。

答案 3 :(得分:0)

这取决于你想要的那个变量。

我怀疑,尽管你最简单的方法是以数据形式存储数据并一直保持这种状态,直到它被返回到客户端应用程序。然后,存储过程可以构建取消结果所需的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

只要最多有一行名称='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)