2011-05-13 37 views
1

我有一个当前使用一个CTE的存储过程。这一个工程像这样:SQL插入临时表而不指定值?

WITH MY_CTE AS 
(
    // Logic here uses SELECT * from a single table. 
) 
SELECT * 
INTO #Tasks 
FROM MY_CTE; 

我现在有一个要求,有选择地调用另一个CTE,将更多的数据添加到原来的临时表。我希望做这样的事情:

IF @Option = 1 
    BEGIN 
     INSERT INTO #Tasks 
     (
      WITH MY_OTHER_CTE 
      (
       // Logic here uses SELECT * from same table as first CTE. 
      ) 
      SELECT * 
      FROM MY_OTHER_CTE 
     ) 
    END 

的问题是,INSERT INTO #Tasks呼叫需要指定VALUES列。来自同一张桌子的CTE的返回记录。原始存储过程的好处在于,即使该表中的列发生更改,它也可以工作,因为我使用的是SELECT *。我可能指定知道他们在共享表中的列,但我失去了这种好处(在这种情况下,这是一个非常有用的好处)。是否有办法完成我想要做的事情,知道他们都是从同一张表中进行选择,并且列总是匹配?

回答

3

这是行不通的?

;WITH MY_OTHER_CTE AS 
(
    // Logic here uses SELECT * from same table as first CTE. 
) 
INSERT INTO #Tasks 
    SELECT * 
    FROM MY_OTHER_CTE 

你可能有另外一个挑战,如果你从(并因此临时表)选择表中有一个标识列

+0

不错,这个工程。我想我只是没有正确的语法。思维详细阐述潜在的身份专栏问题?该表有一个标识列,但它似乎仍然工作正常。第二个CTE没有可能从第一个插入重复数据,所以这是唯一关心的问题?谢谢。 – Ocelot20 2011-05-13 17:51:49

+0

我自己的测试给了我一个标识列的错误:“只有当使用列列表并且IDENTITY_INSERT为ON时,才能指定表'#Tasks'中标识列的显式值。”所以测试,测试,测试,祝你好运。 – 2011-05-13 18:11:42

2

我会义不容辞“列出列,具体开始是很好的做法为6,354个原因。“但我们都去过那里,你不能;-)

无论如何,我会解决这个问题的方式是与派生表&联盟。这里的关键是执行一系列UNION,并使用WHERE标准删除不想运行的查询。显然,所有的表必须相同为了这个工作相同的数据类型,但代码可能看起来像....

WITH MY_CTE AS (

    SELECT * 
    FROM (
     SELECT * 
     FROM FirstTable 
     WHERE <your criteria here> 

      UNION 

     SELECT * 
     FROM FirstTable_OR_SomeOtherTable 
     WHERE <your criteria> 
      AND @Option1 = 1 

      UNION 

     SELECT * 
     FROM OnAndOnAndSoOn 
     WHERE <your criteria> 
      AND @Option2 = 1 

    ) AS MyDerivedTable 
) 
SELECT * 
INTO #Tasks 
FROM MY_CTE; 

编辑

我想我忽略了你的“两CTE的”请求,但我怀疑这会让你到同一个地方。