Oracle多次插入表中用FK检查

时间:2011-08-25 18:52:20

标签: sql oracle10g

我必须在Oracle表中插入许多产品价值记录。我从xls文件中获取所有数据,使用PHP处理它(现在)吐出一个很长的SQL语句。在插入每条记录时,我想检查我从xls中获取的产品ID与数据库中已有的产品,如果ID与产品不匹配,则跳过插入。我试过的陈述如下:

INSERT ALL 
INTO PRODUCTOS_X_PLANES_CATEGORIA(PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR)
    VALUES (NULL, 123456, 81, 10000)
INTO PRODUCTOS_X_PLANES_CATEGORIA(PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR)
    VALUES (NULL, 7890, 76, 11000)
SELECT * FROM DUAL;

哪个给了我一个

[Err] ORA-02291: integrity constraint (OURDB.PXG_PRODUCTO_FKEY) violated - parent key not found

错误消息。我想在尝试插入之前检查PXG_PRODUCTO密钥是否存在。我应该检查PRODUCTOS.PRO_ID字段。我试过像

这样的东西
INSERT ALL 
INTO PRODUCTOS_X_PLANES_CATEGORIA (PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR) 
    VALUES (NULL, 123456, 81, 10000) 
    USING PRODUCTOS ON PXG_PRODUCTO = PRO_ID
INTO PRODUCTOS_X_PLANES_CATEGORIA (PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR) 
    VALUES (NULL, 7890, 76, 11000) 
    USING PRODUCTOS ON PXG_PRODUCTO = PRO_ID
SELECT * FROM DUAL;

只获得

[Err] ORA-00928: missing SELECT keyword

消息。什么是正确的语法?或者,如果我完全错了,我应该做什么呢?

编辑使用

INSERT ALL 
 INTO PRODUCTOS_X_PLANES_CATEGORIA (PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR) VALUES (NULL, 123456, 81, 10000) WHERE EXISTS (SELECT * FROM PRODUCTOS WHERE 123456 = PRO_ID)
 INTO PRODUCTOS_X_PLANES_CATEGORIA (PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR) VALUES (NULL, 7890, 76, 11000) WHERE EXISTS (SELECT * FROM PRODUCTOS WHERE 7890 = PRO_ID)
SELECT * FROM   DUAL;

仍然会导致

[Err] ORA-00928: missing SELECT keyword

3 个答案:

答案 0 :(得分:1)

您可以使用where

INSERT INTO PRODUCTOS_X_PLANES_CATEGORIA 
    (PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR) 
    SELECT NULL, 973082, 76, 10000
    FROM dual
    WHERE EXISTS (SELECT * FROM PRODUCTOS WHERE 973082 = PRO_ID)

答案 1 :(得分:0)

在我们讨论之后,我现在知道您正在动态构造INSERT ALL,每行要插入一个INTO子句:

INSERT ALL 
INTO PRODUCTOS_X_PLANES_CATEGORIA(PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR)
    VALUES (NULL, 123456, 81, 10000)
INTO PRODUCTOS_X_PLANES_CATEGORIA(PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR)
    VALUES (NULL, 7890, 76, 11000)
...
etc.
...
SELECT * FROM DUAL;

您无法将EXISTS检查添加到INTO子句中,因此使用此INSERT ALL语法无法解决您的问题。但是,构建一个巨大的INSERT ALL语句并不是最好的方法。我建议你考虑将值加载到数组中并使用FORALL执行这样的批量插入:

FORALL i IN 1..array.count
  INSERT INTO PRODUCTOS_X_PLANES_CATEGORIA(PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR)
  VALUES (NULL, array(i).PXG_PRODUCTO, array(i).PXG_PLAN_CATEGORIA, array(i).PXG_VALOR);
  SAVE EXCEPTIONS;

您需要了解如何处理异常 - 请参阅documentation

答案 2 :(得分:0)

这样的东西?

INSERT INTO PRODUCTOS_X_PLANES_CATEGORIA 
(PXG_ID, PXG_PRODUCTO, PXG_PLAN_CATEGORIA, PXG_VALOR) 
SELECT NULL AS PXG_ID, PRO_ID AS PXG_PRODUCTO, 76 PXG_PLAN_CATEGORIA, 10000 PXG_VALOR FROM PRODUCTOS WHERE PRO_ID = 973082;