我有一个当前使用一个CTE的存储过程。这个就是这样的:
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 *
。我可以指定知道它们在共享表中的列的列,但是我失去了这个好处(在这个特定情况下是一个非常有用的好处)。有没有办法完成我想要做的事情,知道他们都是从同一个表中选择并且列总是匹配的?
答案 0 :(得分:3)
这有用吗?
;WITH MY_OTHER_CTE AS
(
// Logic here uses SELECT * from same table as first CTE.
)
INSERT INTO #Tasks
SELECT *
FROM MY_OTHER_CTE
如果您选择的表(以及临时表)具有标识列,您可能会遇到另一个挑战
答案 1 :(得分: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”的请求,但我怀疑这会让你到同一个地方。