Oracle 多次插入表并进行 FK 检查

发布于 2024-12-01 11:08:20 字数 1747 浏览 1 评论 0原文

我必须将许多产品价值记录插入 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

I have to insert many product value records into an Oracle table. I get all the data from an xls file, processing it with PHP and (for now) spitting out a long SQL statement. As each record is inserted, I want to check the Product IDs I got from the xls against the products already in the database, skipping the insert if the IDs don't match a product. The statement I tried is the following:

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;

Which gets me an

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

error message. I want to check that the PXG_PRODUCTO key exists before attempting the insert. I should check against the PRODUCTOS.PRO_ID field. I tried something like

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;

getting only a

[Err] ORA-00928: missing SELECT keyword

message. What's the correct syntax? Or, if I'm completely wrong, what should I be doing instead?

EDIT Using

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;

still results in

[Err] ORA-00928: missing SELECT keyword

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

挽梦忆笙歌 2024-12-08 11:08:20

您可以使用 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)

You could use 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)
×纯※雪 2024-12-08 11:08:20

像这样的东西吗?

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;

Something like this?

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;
漫雪独思 2024-12-08 11:08:20

经过我们的讨论,我现在知道您正在动态构造 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;

您无法向 INTO 子句添加 EXISTS 检查,因此没有解决方案使用此 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;

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

After our discussion, I now know that you are constructing the INSERT ALL dynamically, with one INTO clause per row of data to be inserted:

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;

You can't add an EXISTS check to the INTO clause, and so there isn't a solution to your problem using this INSERT ALL syntax. However, constructing a huge INSERT ALL statement is not the best way to do this anyway. I suggest you look into loading the values into arrays and using FORALL to perform a bulk insert like this:

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;

You'll need to understand how exceptions are handled - see documentation

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文