Многократная вставка Oracle в таблицу с проверкой FK - PullRequest
0 голосов
/ 25 августа 2011

Мне нужно вставить много записей о стоимости продукта в таблицу Oracle. Я получаю все данные из файла xls, обрабатываю их с помощью PHP и (пока) выкладываю длинный SQL-оператор. Поскольку каждая запись вставлена, я хочу проверить идентификаторы продуктов, которые я получил от xls, по продуктам, уже имеющимся в базе данных, пропуская вставку, если идентификаторы не соответствуют продукту. Утверждение, которое я пробовал, выглядит следующим образом:

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 ]

1 голос
/ 25 августа 2011

Вы можете использовать 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)
0 голосов
/ 26 августа 2011

Как то так?

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;
0 голосов
/ 26 августа 2011

После нашего обсуждения я теперь знаю, что вы создаете 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;

Вам необходимо понять, как обрабатываются исключения - см. документация

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...