【问题标题】:SQL Server CTE with multiple insert statements具有多个插入语句的 SQL Server CTE
【发布时间】:2018-03-20 21:42:11
【问题描述】:

我可以在 SQL Sever 中使用多个 CTE INSERT 表达式吗?

这在 PostgreSQL 中是允许的:

writeable common table expression and multiple insert statements

例如在 PostgreSQL 中。

with foo as 
(
      select * from ...
),
b as 
(
      insert into bar
          select * from foo
          returning *
)
insert into baz
    select * from foo;

我已经在 SQL Server 中尝试过:

;WITH cte1 AS 
(
    SELECT * FROM Foo       
),
cte2 AS ( -- depends on cte1
    SELECT * FROM Bar WHERE ID IN (SELECT ID FROM cte1)
),
cte3 AS ( -- first insert
    INSERT INTO Baz1
    OUTPUT INSERTED.*
    SELECT * FROM cte2
)
INSERT INTO Baz2 -- second insert depends on ct3 data-set
SELECT * FROM cte3

上述方法不起作用。

【问题讨论】:

  • 不,SQL Server 不支持
  • @a_horse_with_no_name,那我有什么选择呢?我应该在第一次插入时写入临时表吗?然后把它移到真正的两张桌子上?
  • 您可以在 cte 中加入 foo 到 bar。
  • @JoeC,是的,我知道,但这不是我的问题。以上只是一个简化的例子。
  • 您可能需要将第一个插入写入临时表并执行其余逻辑。嵌套 CTE 中不允许有多个 insertsql se。

标签: sql-server common-table-expression


【解决方案1】:

对于您的情况,我会考虑在 MS SQL Server 中使用 trigger(加上它可以访问的 inserted 临时表)- 可以找到更多信息 here。另一个有用的链接here

我如何解决您的问题是将其视为两个独立的代码块:

  • 第一个块(从两个 CTE 运行第一个插入语句):
;WITH cte1 AS 
(
    SELECT * FROM Foo       
),
cte2 AS ( -- depends on cte1
    SELECT * FROM Bar WHERE ID IN (SELECT ID FROM cte1)
)
INSERT INTO Baz1
SELECT * 
FROM cte2
  • 第二块(存在于 Baz1 表中的触发器,在 INSERT 到表中之后运行):
CREATE TRIGGER [Some_unique_trigger_name] ON Baz1
AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;
    INSERT INTO Baz2(
        column_names
    )
    SELECT *
    FROM inserted i
END

您必须首先更新查询以匹配列名/表名/触发器名称等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多