Oracle 多次插入表并进行 FK 检查
我必须将许多产品价值记录插入 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
where
:You could use
where
:像这样的东西吗?
Something like this?
经过我们的讨论,我现在知道您正在动态构造 INSERT ALL,每行要插入的数据有一个 INTO 子句:
您无法向 INTO 子句添加 EXISTS 检查,因此没有解决方案使用此 INSERT ALL 语法解决您的问题。然而,构造一个巨大的 INSERT ALL 语句无论如何都不是执行此操作的最佳方法。我建议您考虑将值加载到数组中并使用 FORALL 执行批量插入,如下所示:
您需要了解如何处理异常 - 请参阅 文档
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:
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:
You'll need to understand how exceptions are handled - see documentation