2013-07-17 3 views
0

У меня есть утилита резервного копирования, работающая в разделе восстановления. Это мой стол:Oracle MERGE и подготовленный оператор

CREATE TABLE "SBOOKS"."DEV_CORPUS" 
    ( "CORPUSID" NUMBER(9,0) NOT NULL ENABLE, 
    "CORPUS_NAME" VARCHAR2(768 BYTE) NOT NULL ENABLE, 
    "CORPUSLASTSYNC" DATE, 
    PRIMARY KEY ("CORPUSID") 

В восстановлении класса я хотел бы посмотреть на первичный ключ в таблице, если она существует, то обновить строку, если нет, то вставить строку.
Теперь проблема в том, что мне нужно передать параметры из класса (они не существуют в какой-либо таблице), как я могу это сделать? Каково ваше предложение? используя подготовленное состояние или что? и как? укажите примеры или ссылки на источники.

Дополнительная информация: Я использую разработчик oracle sql и java netbeans.

EDIT: Я пытаюсь это в командном окне:

MERGE INTO dev_corpus a 
    USING (SELECT corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain FROM dual WHERE corpusId = 1000156 AND corpus_name = 'sahar' AND corpusdesc = 'sahaaaaa' AND corpusimageids IS NULL AND rocf1 IS NULL AND rocf2 IS NULL AND rocf3 IS NULL AND rocc1 IS NULL AND rocc2 IS NULL AND rocc3 IS NULL AND corpusactive IS NULL AND corpusrunfrequency IS NULL AND corpuslastrun IS NULL AND corpuslastsync IS NULL AND rocsettingid IS NULL AND corpusaffinity IS NULL AND corpusterms IS NULL AND corpusdomain IS NULL) incoming 
    ON (a.corpusid = incoming.corpusid) 
    WHEN MATCHED THEN 
    UPDATE SET corpusid = incoming.corpusid , corpus_name = incoming.corpus_name , corpusdesc = incoming.corpusdesc , corpusimageids = incoming.corpusimageids , rocf1 = incoming.rocf1 , rocf2 = incoming.rocf2 , rocf3 = incoming.rocf3 , rocc1 = incoming.rocc1 , rocc2 = incoming.rocc2 , rocc3 = incoming.rocc3 , corpusactive = incoming.corpusactive , corpusrunfrequency = incoming.corpusrunfrequency , corpuslastrun = incoming.corpuslastrun , corpuslastsync = incoming.corpuslastsync , rocsettingid = incoming.rocsettingid , corpusaffinity = incoming.corpusaffinity , corpusterms = incoming.corpusterms , corpusdomain = incoming.corpusdomain 
    WHEN NOT MATCHED THEN 
    INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) 
    VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain) 

это реальная таблица:

CREATE TABLE "SBOOKS"."DEV_CORPUS" 
    ( "CORPUSID" NUMBER(9,0) NOT NULL ENABLE, 
    "CORPUS_NAME" VARCHAR2(768 BYTE) NOT NULL ENABLE, 
    "CORPUSDESC" VARCHAR2(4000 BYTE), 
    "CORPUSIMAGEIDS" VARCHAR2(768 BYTE), 
    "ROCF1" FLOAT(63), 
    "ROCF2" FLOAT(63), 
    "ROCF3" FLOAT(63), 
    "ROCC1" FLOAT(63), 
    "ROCC2" FLOAT(63), 
    "ROCC3" FLOAT(63), 
    "CORPUSACTIVE" NUMBER(3,0), 
    "CORPUSRUNFREQUENCY" NUMBER(3,0), 
    "CORPUSLASTRUN" DATE, 
    "CORPUSLASTSYNC" DATE, 
    "ROCSETTINGID" NUMBER(3,0), 
    "CORPUSAFFINITY" NUMBER(3,0), 
    "CORPUSTERMS" VARCHAR2(4000 BYTE), 
    "CORPUSDOMAIN" NUMBER(3,0), 
    PRIMARY KEY ("CORPUSID") 

бросает мне эту ошибку:

Error at Command Line:2 Column:644 
Error report: 
SQL Error: ORA-00904: "CORPUSDOMAIN": invalid identifier 
00904. 00000 - "%s: invalid identifier" 
*Cause:  
*Action: 

.

Я не знаю, чего у меня нет. У тебя есть идея?

Спасибо!

EDIT2: наконец это работает в COMAND победу:

MERGE INTO dev_corpus a 
    USING (SELECT 1000156 corpusid, 'sss2' corpus_name, 'sahaaaaaar' corpusdesc, null corpusimageids, null rocf1, null rocf2, null rocf3, null rocc1, null rocc2, null rocc3, null corpusactive, null corpusrunfrequency, null corpuslastrun, null corpuslastsync, null rocsettingid, null corpusaffinity, null corpusterms, null corpusdomain FROM dual) incoming 
    ON (a.corpusid = incoming.corpusid) 
    WHEN MATCHED THEN 
    UPDATE SET corpus_name = incoming.corpus_name , corpusdesc = incoming.corpusdesc , corpusimageids = incoming.corpusimageids , rocf1 = incoming.rocf1 , rocf2 = incoming.rocf2 , rocf3 = incoming.rocf3 , rocc1 = incoming.rocc1 , rocc2 = incoming.rocc2 , rocc3 = incoming.rocc3 , corpusactive = incoming.corpusactive , corpusrunfrequency = incoming.corpusrunfrequency , corpuslastrun = incoming.corpuslastrun , corpuslastsync = incoming.corpuslastsync , rocsettingid = incoming.rocsettingid , corpusaffinity = incoming.corpusaffinity , corpusterms = incoming.corpusterms , corpusdomain = incoming.corpusdomain 
    WHEN NOT MATCHED THEN 
    INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) 
    VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain) 

но в классе Java nooot работает в случаях обновления, но если это случай вставки он будет работать. В случае обновления он не будет бросать какую-либо ошибку, он просто зависает до тех пор, пока я не удалю запись из БД, тогда он вставляет его, поэтому никакого обновления !. Вы находите что-то не так в этом коде?

preparedStatement = dbConnection.prepareStatement("MERGE INTO dev_corpus a " + 
           "USING (SELECT ? corpusid, ? corpus_name, ? corpusdesc, ? corpusimageids, ? rocf1, ? rocf2, ? rocf3, ? rocc1, ? rocc2, ? rocc3, ? corpusactive, ? corpusrunfrequency, ? corpuslastrun, ? corpuslastsync, ? rocsettingid, ? corpusaffinity, ? corpusterms, ? corpusdomain FROM dual) incoming " + 
           "ON (a.corpusid = incoming.corpusid) " + 
           "WHEN MATCHED THEN " + 
           "UPDATE SET corpus_name = incoming.corpus_name , corpusdesc = incoming.corpusdesc , corpusimageids = incoming.corpusimageids , rocf1 = incoming.rocf1 , rocf2 = incoming.rocf2 , rocf3 = incoming.rocf3 , rocc1 = incoming.rocc1 , rocc2 = incoming.rocc2 , rocc3 = incoming.rocc3 , corpusactive = incoming.corpusactive , corpusrunfrequency = incoming.corpusrunfrequency , corpuslastrun = incoming.corpuslastrun , corpuslastsync = incoming.corpuslastsync , rocsettingid = incoming.rocsettingid , corpusaffinity = incoming.corpusaffinity , corpusterms = incoming.corpusterms , corpusdomain = incoming.corpusdomain " + 
           "WHEN NOT MATCHED THEN " + 
           "INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) " + 
           "VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain)"); 

спасибо!

+0

Непонятно, используете ли вы MySQL или Oracle. Вы используете то или другое? Или оба? Если вы используете Oracle, вам нужно «MERGE», и если вы используете MySQL, вам нужно «INSERT ... ON DUPLICATE KEY». Что касается проблем с синтаксисом, я считаю, что лучше всего выработать запрос в командном окне, а затем, когда он выглядит хорошо, вы можете реализовать его в Java-коде. –

+0

@ Эд Гиббс: извините, мой плохой, разработчик sql sql. PLZ см. выше код edites. – user149855

ответ

1

Если вы используете Oracle, вам нужно сосредоточиться на инструкции MERGE - INSERT ... ON DUPLICATE KEY не работает в Oracle.

Я не знаю, если это единственная проблема, но есть некоторые синтаксические ошибки в MERGE вы публикуемый:

MERGE INTO dev_corpus a 
USING (SELECT * FROM dual WHERE (corpusid=?, corpus_name=?, corpuslastsync=?) 
           ^^^^^^^^^^^^^^^^^^^^^^ (1) 
ON (a.corpusid = incoming.corpusid) 
WHEN MATCHED THEN 
UPDATE SET (a.corpus_name = incoming.corpus_name AND a.corpuslastsync = incoming.corpuslastsync) 
      ^^^^^^^^^^^^^^^^^^ (2) 
WHEN NOT MATCHED THEN 
INSERT (a.corpusid, a.corpus_name, a.corpuslastsync) 
VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpuslastsync) 

Задача (1): у Вас есть незаконченная скобка, плюс многократные WHERE условия должны быть разделены AND, а не запятой.Вот исправленная версия, с отступом так что не требуется горизонтальная прокрутка:

USING (
    SELECT * FROM dual 
    WHERE (corpusid=? AND corpus_name=? AND corpuslastsync=?)) 

Скобки, окружающие WHERE условия не являются обязательными в этом случае, так что это будет работать также:

USING (
    SELECT * FROM dual 
    WHERE corpusid=? AND corpus_name=? AND corpuslastsync=?) 

Проблема (2): Скобки после SET, и здесь вам нужна запятая вместо AND. Он должен выглядеть следующим образом (как описано выше, я отступ это так что он может быть прочитан без горизонтальной прокрутки)

UPDATE SET 
    a.corpus_name = incoming.corpus_name, 
    a.corpuslastsync = incoming.corpuslastsync 

Это должно заботиться о синтаксических ошибках, но, конечно, нет никакой гарантии, ваши результаты будут как ожидаемый :)

Наконец, как я уже упоминал в комментариях, попробуйте это в SQLPlus или SQL Developer, используя тестовые значения (а не параметры). Это будет намного проще. Когда у вас есть корректное поведение MERGE, вы можете переместить его в код Java и параметризовать его. Удачи!


Дополнение к обновленному вопрос

Прежде всего, хорошие новости вы используете SQL Developer, чтобы решить эту проблему! Пренебрежение моим последним абзацем выше :)

Во-вторых, ваш адрес включает в себя AND corpuslastsync = null. При проверке на нуль, вам нужно IS NULL, не = NULL:

... AND corpuslastsync IS NULL 

Наконец, я уверен, что конкретная ошибка вы получаете с вашей последней попытки из-за псевдонимами в этой строке:

INSERT (a.corpusid, a.corpus_name, a.corpuslastsync) 

Попробуйте вместо этого:

INSERT (corpusid, corpus_name, corpuslastsync) 

Oracle знает, что столбцы, названные здесь принадлежат dev_corpus таблице, псевдонимами, как a.

+0

Большое вам спасибо. Но все еще не работает :(. Plz см. Отредактированный вопрос – user149855

+1

Можете ли вы попробовать удалить псевдонимы 'a.' в части' UPDATE'? Вместо 'SET a.corpusid = incoming.corpusid и т. Д. попробуйте 'SET corpusid = входящий.corpusid'. –

+0

thans снова, но все еще не работает, другая ошибка, хотя, plz видит отредактированный запрос. – user149855

1

Наконец это работает !, так вот запрос для команды SQL:

MERGE INTO dev_corpus a 
    USING (SELECT 1000156 corpusid, 'sss2' corpus_name, 'sahaaaaaar' corpusdesc, null corpusimageids, null rocf1, null rocf2, null rocf3, null rocc1, null rocc2, null rocc3, null corpusactive, null corpusrunfrequency, null corpuslastrun, null corpuslastsync, null rocsettingid, null corpusaffinity, null corpusterms, null corpusdomain FROM dual) incoming 
    ON (a.corpusid = incoming.corpusid) 
    WHEN MATCHED THEN 
    UPDATE SET corpus_name = incoming.corpus_name , corpusdesc = incoming.corpusdesc , corpusimageids = incoming.corpusimageids , rocf1 = incoming.rocf1 , rocf2 = incoming.rocf2 , rocf3 = incoming.rocf3 , rocc1 = incoming.rocc1 , rocc2 = incoming.rocc2 , rocc3 = incoming.rocc3 , corpusactive = incoming.corpusactive , corpusrunfrequency = incoming.corpusrunfrequency , corpuslastrun = incoming.corpuslastrun , corpuslastsync = incoming.corpuslastsync , rocsettingid = incoming.rocsettingid , corpusaffinity = incoming.corpusaffinity , corpusterms = incoming.corpusterms , corpusdomain = incoming.corpusdomain 
    WHEN NOT MATCHED THEN 
    INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) 
    VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain) 

и здесь является Java-код с помощью pstmt:

preparedStatement = dbConnection.prepareStatement("MERGE INTO dev_corpus a " + 
           "USING (SELECT ? corpusid, ? corpus_name, ? corpusdesc, ? corpusimageids, ? rocf1, ? rocf2, ? rocf3, ? rocc1, ? rocc2, ? rocc3, ? corpusactive, ? corpusrunfrequency, ? corpuslastrun, ? corpuslastsync, ? rocsettingid, ? corpusaffinity, ? corpusterms, ? corpusdomain FROM dual) incoming " + 
           "ON (a.corpusid = incoming.corpusid) " + 
           "WHEN MATCHED THEN " + 
           "UPDATE SET a.corpus_name = incoming.corpus_name , a.corpusdesc = incoming.corpusdesc , a.corpusimageids = incoming.corpusimageids , a.rocf1 = incoming.rocf1 , a.rocf2 = incoming.rocf2 , a.rocf3 = incoming.rocf3 , a.rocc1 = incoming.rocc1 , a.rocc2 = incoming.rocc2 , a.rocc3 = incoming.rocc3 , a.corpusactive = incoming.corpusactive , a.corpusrunfrequency = incoming.corpusrunfrequency , a.corpuslastrun = incoming.corpuslastrun , a.corpuslastsync = incoming.corpuslastsync , a.rocsettingid = incoming.rocsettingid , a.corpusaffinity = incoming.corpusaffinity , a.corpusterms = incoming.corpusterms , a.corpusdomain = incoming.corpusdomain " + 
           "WHEN NOT MATCHED THEN " + 
           "INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) " + 
           "VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain)"); 

у вас есть создать таблицу в разделе вопросов , надеюсь, это поможет кому-то! :)

Смежные вопросы