【问题标题】:Insert into inside cross apply插入内交叉应用
【发布时间】:2014-09-24 17:41:19
【问题描述】:
    SELECT DISTINCT CODE
    FROM   T1
    CROSS APPLY 
    (
        INSERT  INTO T4(TEXT1, TEXT2, TEXT3)
        SELECT  T2.TEXT1, T2.TEXT2, T3.TEXT3
        FROM    T2,
                T3
        WHERE   T2.ID = T3.ID
        AND     T2.CODE = T1.CODE
    ) AS T

使用执行此查询时出现此错误:

嵌套的 INSERT、UPDATE、DELETE 或 MERGE 语句必须有 OUTPUT 子句。

我做错了什么?

编辑

我打算实现的是模拟一个 WHILE..LOOP。 循环遍历 T1 中的所有 CODE,并为每个 CODE 从 T2 和 T3 中获取 TEXT 字段(将它们与 ID 连接起来)并将它们插入到表 T4 中。

我正在尝试通过 CODE 分隔插入,因为两个表都有大量数据并且我正在尝试提高性能(也许?!)

【问题讨论】:

  • 你为什么要做这样的插入?你到底想完成什么?
  • 对于 T1 表中的每个 ID,将 TEX1、2 和 3 插入到 FINAL 表中。
  • 您是只是尝试进行插入,还是进行插入并在之后获得结果?该语法令人困惑,您的解释与您编写的代码不完全同步
  • 通过外部交叉应用,您可以从表 T1 中获得所有 ID 的列表;它们是否在 T2/T3 中具有已插入的等效部分。我不确定这真的是你想要得到的,但你没有描述你最终想要得到的确切结果;因此无法告诉您是否存在更简单的解决方案。
  • 这正是我的回答。

标签: sql sql-server tsql


【解决方案1】:

猜测

INSERT  INTO FINAL (TEXT1   , TEXT2   , TEXT3)
SELECT  DISTINCT    T2.TEXT1, T2.TEXT2, T3.TEXT3
  FROM  T1
  JOIN  T2
   on   T2.ID = T1.ID
  JOIN  T3
    on  T3.VALUE = T2.VALUE 

【讨论】:

    【解决方案2】:

    你不能做你想做的事。语言不允许你。为了做好准备,我创建了以下 3 个表格

    SET NOCOUNT ON;
    CREATE TABLE dbo.Final
    (
        ID int IDENTITY(1,1) NOT NULL
    ,   text1 varchar(50) NOT NULL
    ,   text2 varchar(50) NOT NULL
    ,   text3 varchar(50) NOT NULL
    );
    
    CREATE TABLE dbo.Chain
    (
        ID int NOT NULL
    );
    
    CREATE TABLE dbo.Chained
    (
        ID int NOT NULL
    ,   Foo int NOT NULL
    );
    

    只是为了演示 OUTPUT 子句的位置,我们将插入 4 行并查看漂亮漂亮的 INSERTED 虚拟表和相关的 ID 值。

    -- Works
        INSERT INTO
            dbo.Final
        (
            text1
        ,   text2
        ,   text3
        )
        OUTPUT
            INSERTED.*
        SELECT
            D.t1
        ,   D.t2
        ,   D.t3    
        FROM
        (
            VALUES
                ('A', 'B', 'C')
            ,   ('D', 'B', 'C')
            ,   ('G', 'B', 'C')
            ,   ('J', 'B', 'C')
        ) D (t1,t2,t3);
    

    现在,如果我执行以下语句,它将正常工作。但是,如果我忽略 INSERT 只是为了直观地检查我想要放入表中的内容,SQL Server 将引发以下错误

    在不是 INSERT 语句的直接行源的 SELECT 语句中不允许嵌套的 INSERT、UPDATE、DELETE 或 MERGE 语句。

    -- Comment out the insert portion to generate
    -- A nested INSERT, UPDATE, DELETE, or MERGE statement is not allowed in a SELECT statement that is not the immediate source of rows for an INSERT statement.
    INSERT INTO
        dbo.Chain
    (
        ID
    )
    SELECT
        X.ID
    FROM
    (
        INSERT INTO
            dbo.Final
        (
            text1
        ,   text2
        ,   text3
        )
        OUTPUT
            INSERTED.*
        SELECT
            D.t1
        ,   D.t2
        ,   D.t3    
        FROM
        (
            VALUES
                ('A', 'B', 'C')
            ,   ('D', 'B', 'C')
            ,   ('G', 'B', 'C')
            ,   ('J', 'B', 'C')
        ) D (t1,t2,t3)
    ) x
    

    但是,您想加倍努力并应用,或者将虚拟表的结果与其他东西连接起来,这不会奏效。

    嵌套的 INSERT、UPDATE、DELETE 或 MERGE 语句不允许在 JOIN 或 APPLY 运算符的任何一侧。

    我想这只是一个级别的复杂性太多了。

    -- Now, try the same bit except we use the derived table as a JOIN/APPLY
    -- Can't fix what's not supported 
    -- A nested INSERT, UPDATE, DELETE, or MERGE statement is not allowed on either side of a JOIN or APPLY operator.
    INSERT INTO
        dbo.Chained
    (
        ID
    ,   Foo
    )
    SELECT
        X.ID
    ,   D.foo
    FROM
    (
        VALUES
        (1)
    ) D(Foo)
    CROSS APPLY
    (
        INSERT INTO
            dbo.Final
        (
            text1
        ,   text2
        ,   text3
        )
        OUTPUT
            INSERTED.*
        SELECT
            D.t1
        ,   D.t2
        ,   D.t3    
        FROM
        (
            VALUES
                ('A', 'B', 'C')
            ,   ('D', 'B', 'C')
            ,   ('G', 'B', 'C')
            ,   ('J', 'B', 'C')
        ) D (t1,t2,t3)
    ) x;
    

    如果你真的需要这样的东西,那么你必须把它分解成单独的语句。

    【讨论】:

      猜你喜欢
      • 2015-06-12
      • 1970-01-01
      • 2019-01-10
      • 2016-12-07
      • 2014-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-11
      相关资源
      最近更新 更多