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我知道原因可能是:
- 带有 ORDER BY 子句或 INNER JOIN 的 INSERT 语句
- 带有 INNER JOIN 或 ORDER BY 子句的 DELETE 语句
- 带有 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 对应项的行
我偶然解决了我的问题,但我真的很想知道它为什么有效:),
事情是这样的:
当我执行以下 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我知道原因可能是:
- 带有 ORDER BY 子句或 INNER JOIN 的 INSERT 语句
- 带有 INNER JOIN 或 ORDER BY 子句的 DELETE 语句
- 带有 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 对应项的行