ORA-00933: SQL 命令未以 INSERT INTO...SELECT 语句正确结束

ORA-00933: SQL command not properly ended with INSERT INTO...SELECT statement

我偶然解决了我的问题,但我真的很想知道它为什么有效:),

事情是这样的:

当我执行以下 SQL 语句时出现 ORA-00933: SQL command not properly ended 错误:

  INSERT INTO BASP_DX.QLR@GT(BDCDYH, QSZT)
  SELECT NVL(e.BDCDYH, ' '),b.LIFECYCLE AS QSZT
  FROM DJ_DY a
    LEFT JOIN DJ_XGDJGL d
      ON d.ZSLBH = a.SLBH
    LEFT JOIN DJ_DJB e
      ON e.SLBH = d.FSLBH
        AND e.SLBH = '0123456789'
    LEFT JOIN DJ_QLRGL f
      ON f.SLBH = e.SLBH
        AND f.QLRLX = 'Person1'
    LEFT JOIN DJ_QLRGL b
      ON b.SLBH = a.SLBH
        AND (b.QLRLX = 'Person2' OR (b.QLRLX = 'Person3' AND b.QLRID = f.QLRID))
  WHERE a.SLBH = '12345'
    AND e.SLBH IS NOT NULL
    -- add the condition to ensure that 
    -- this statement and the second statement get the same result 
    AND b.QLRID IS NOT NULL
    AND (a.LIFECYCLE = '0' OR a.LIFECYCLE IS NULL);

我从原始 SQL 语句中删除了所有不必要的插入值、相关 table 和条件,以专注于问题部分。

那我就google吧,从这个post我知道原因可能是:

  1. 带有 ORDER BY 子句或 INNER JOIN 的 INSERT 语句
  2. 带有 INNER JOIN 或 ORDER BY 子句的 DELETE 语句
  3. 带有 INNER JOIN 的 UPDATE 语句

显然,这些不是我喜欢的类型。我没有用INNER JOIN和ORDER BY,我用的都是LEFT JOIN语句,所以我想可能是我用LEFT JOIN语句设置了太多的条件(比如LEFT JOIN DJ_QLRGL b),所以我尝试在 WHERE 子句之后移动条件,它看起来像这样:

  INSERT INTO BASP_DX.QLR@GT(BDCDYH, QSZT)
  SELECT NVL(e.BDCDYH, ' '),b.LIFECYCLE AS QSZT
  FROM DJ_DY a
    LEFT JOIN DJ_XGDJGL d
      ON d.ZSLBH = a.SLBH
    LEFT JOIN DJ_DJB e
      ON e.SLBH = d.FSLBH
        AND e.SLBH = '0123456789'
    LEFT JOIN DJ_QLRGL f
      ON f.SLBH = e.SLBH
        AND f.QLRLX = 'Person1'
    LEFT JOIN DJ_QLRGL b
      ON b.SLBH = a.SLBH
    -- this conditions move to WHERE clause
  WHERE a.SLBH = '12345'
    AND e.SLBH IS NOT NULL
    -- here is the original LEFT JOIN condition
    AND (b.QLRLX = 'Person2' OR (b.QLRLX = 'Person3' AND b.QLRID = f.QLRID))
    AND (a.LIFECYCLE = '0' OR a.LIFECYCLE IS NULL);

那就成功了! 但是为什么?

我只想知道出现这种情况的原因


Solution

问题是三角连接,LEFT JOIN 条件不能包含关于自连接的条件 table,在这种情况下,它是 b.QLRID = f.QLRID,所以当我删除 b.QLRID = f.QLRID条件,有效。

首先,"DJ_QLRGL b" 的连接不再是 LEFT, 因为 WHERE 条件排除了没有找到 b 对应项的行