2015-08-12 2 views
-3

Я хочу выполнить несколько операторов вставки sql, которые хранятся в строке в java. Ниже строка:Как вставить несколько вложенных операторов в oracle

insert_string = "INSERT INTO temp values(TO_DATE ('12-08-15', 'DD/MM/RRRR') - 1, 'rahul', 'START', '12-08-15 06:32:33.577676 PM'); 
INSERT INTO temp values(TO_DATE ('12-08-15', 'DD/MM/RRRR') - 1, 'abhishek', 'START', '12-08-15 06:32:33.577676 PM');" 

я пытался выполнить его batchExecute(), но он не работает для меня. Пожалуйста, предложите, что мне делать?

+0

Является ли ** batchExecute ** вызовом из java-библиотеки (то есть JDBC или JPA или Hibernate и т. Д.) Или непосредственно в базу данных? – whyceewhite

+0

Вы можете пройти, завернув инструкции в анонимный блок PL/SQL, но это имеет свои собственные ограничения. '" BEGIN INSERT ...; INSERT ...; END; ' –

ответ

3

Вот отредактированный пример из: https://docs.oracle.com/javase/tutorial/jdbc/basics/retrieving.html, из раздела Использования Соглашения объектов для пакетного обновления

Похоже, вам нужно разделить ваши insert_string между партией звонков следующим образом:

Connection con = createConnection(); // Get the connection somehow 
Statement stmt = null; 

try { 
    con.setAutoCommit(false); 
    stmt = con.createStatement(); 

    stmt.addBatch("INSERT INTO temp values(" + 
     " TO_DATE('12-08-15','DD/MM/RRRR') - 1, " + 
     " 'rahul', 'START', '12-08-15 06:32:33.577676 PM') "); 

    stmt.addBatch("INSERT INTO temp values(" + 
     " TO_DATE ('12-08-15','DD/MM/RRRR') - 1, " + 
     " 'abhishek','START','12-08-15 06:32:33.577676 PM') "); 

    // ...the rest of the statements 

    int [] updateCounts = stmt.executeBatch(); 

    con.commit(); // don't forget to call commit 

} catch(BatchUpdateException b) { 
    // Handle this Batch Update Exception 
} catch(SQLException ex) { 
    // Handle regular SQL Exception; 
} finally { 
    // Make sure to call this. 
    if (stmt != null) { stmt.close(); } 
     con.setAutoCommit(true); 
} 
+0

Также я не проверял, будет ли' TO_DATE (...) 'в вызове API JDBC работать так же, как в PL/SQL.Возможно, вам придется манипулировать датой, используя 'java.util.Calendar' вне строки SQL. – Marin

+0

Спасибо, марин за ваш ответ. но разве это невозможно без разделения строки? – netdamin

+0

Я попробовал 'stmt.execute()' вместо 'stmt.addBatch' для всего набора команд как одну строку, но это не сработает. Если у вас уже есть текст, который нужно выполнить, и хотите сделать это с Java, этот раздел может помочь вам лучше: http://stackoverflow.com/questions/1044194/running-a-sql-script-using-mysql-with -jdbc – Marin

2

Различные ответы SO, такие как this one и this one, подразумевают, что вы не можете использовать свой текущий подход.

Ответ Марин (который я одобрил) показывает, как выполнять отдельные инструкции INSERT.

Вы также можете сделать это в одном запросе, используя оператор INSERT ALL. Как с ответом Марин, вам нужно изменить ваш SQL:

INSERT ALL 
    INTO temp values(TO_DATE ('12-08-15', 'DD/MM/RRRR') - 1, 'rahul', 'START', '12-08-15 06:32:33.577676 PM') 
    INTO temp values(TO_DATE ('12-08-15', 'DD/MM/RRRR') - 1, 'abhishek', 'START', '12-08-15 06:32:33.577676 PM') 
    SELECT * FROM DUAL;"; 

Кроме того, я бы избежать форматной строки RRRR, если не случится работать с не-Y2K совместимого приложения или это ваша заветная мечта, чтобы Создай. Принимая это шаг вперед, вы даже не нужно TO_DATE здесь потому, что Oracle поддерживает дату ANSI синтаксис литерала:

INSERT ALL 
    INTO temp values(DATE '2015-12-08' - 1, 'rahul', 'START', '12-08-15 06:32:33.577676 PM') 
    INTO temp values(DATE '2015-12-08' - 1, 'abhishek', 'START', '12-08-15 06:32:33.577676 PM') 
    SELECT * FROM DUAL; 

Дополнение

В случае последний столбец вставляется отметка времени типа, я бы рекомендовал использовать литерал timestamp ANSI. Если вы полагаетесь на неявное преобразование, используя формат отображения по умолчанию, это опасная практика, потому что кто-то может сломать ваш код, просто изменив формат отображения временной метки по умолчанию.

Ответ обновляются со значениями временных меток ANSI выглядит следующим образом (для дорожит ANSI необходимо использовать 24-часовой):

INSERT ALL 
    INTO temp values(DATE '2015-12-08' - 1, 'rahul', 'START', TIMESTAMP '2015-12-08 18:32:33.577676') 
    INTO temp values(DATE '2015-12-08' - 1, 'abhishek', 'START', TIMESTAMP '2015-12-08 18:32:33.577676') 
    SELECT * FROM DUAL; 

Поймите, что при указании даты и метки времени значения, как это ваш Oracle код работает каждый раз, когда, независимо от текущей настройки сеанса или даты базы данных/времени.

Конечно, поскольку вы делаете это через Java, еще лучший подход заключается в использовании подготовленных операторов. Они также невосприимчивы к настройкам формата даты/времени, плюс еще более важное преимущество защиты от SQL-инъекции.

+0

Это не литералы даты ANSI Oracle. Лимит даты начинается с ключевого слова 'date' и не содержит времени: https://docs.oracle.com/database/121/SQLRF/sql_elements003.htm#sthref329. То, что вы делаете, - это неявное преобразование с использованием спецификации формата в 'NLS_DATE_FORMAT'. –

+0

Я имел в виду первые даты в каждой строке ('DATE '2015-12-08''), где OP имела явное преобразование на сегодняшний день. Я не беспокоился о временных значениях, потому что я не был уверен, действительно ли они были типом TIMESTAMP, не было явного преобразования в 'INSERT' и' MM-DD-YY HH: MI: SS.FF6 AM' (или, может быть, даже «MM-DD-RR ...») в лучшем случае является необычным «NLS_TIMESTAMP_FORMAT». Во всяком случае, я благодарю вас за это: если это временная метка, я обновлю свой ответ и объясню тип ANSI TIMESTAMP :) –

+0

Плохо, я искал неправильную часть строки. –

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