Intereting Posts
SAS proc sql внутри% macro Escaping Question Mark (?) В SQL WHERE Обмен таблицами ms-sql Как подсчитать только первое вхождение значения? Как использовать не существует в sql-запросе с w3schools? Как группировать по 2 полям и упорядочивать по дате одновременно? MySql Как установить локальную переменную в инструкции обновления (синтаксис?) Типы полей, доступные для использования с «CREATE TABLE» в Microsoft Access Разница между предложениями ON и WHERE в таблицах SQL-таблицы Захват SQL-инъекций и других вредоносных веб-запросов Ошибка SQL с указанием недопустимого имени столбца, если у меня есть проверка, если она существует. Зачем? Найдите число, которое находится между двумя значениями, и поле возврата, соответствующее более низкому значению Всего полей сумм из объединенных таблиц Запрос MySQL с использованием оператора «in»: почему разные результаты w / quotes? Рекурсивный запрос

запустить скрипт oracle sql из java

У меня есть куча sql-скриптов, которые должны обновлять базу данных при запуске Java-приложения.

Я попытался использовать скрипт ibatis, но он славно справляется при определении триггеров, где «;» символ не обозначает конец инструкции.

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

public class ScriptRunner { private final DataSource ds; public ScriptRunner(DataSource ds) { this.ds = ds; } public void run(InputStream sqlStream) throws SQLException, IOException { sqlStream.reset(); final Statement statement = ds.getConnection().createStatement(); List<String> sqlFragments = createSqlfragments(sqlStream); for (String toRun : sqlFragments) { if (toRun.length() > 0) { statement.execute(toRun); } } } private static List<String> createSqlfragments(InputStream sqlStream) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(sqlStream)); List<String> ret = new ArrayList<String>(); String line; StringBuilder script = new StringBuilder(); while ((line = br.readLine()) != null) { if (line.equals("/")) { ret.add(removeMultilineComments(script)); script = new StringBuilder(); } else { //strip comments final int indexComment = line.indexOf("--"); String lineWithoutComments = (indexComment != -1) ? line.substring(0, indexComment) : line; script.append(lineWithoutComments).append(" "); } } if (script.length() > 0) { ret.add(removeMultilineComments(script)); } return ret; } private static String removeMultilineComments(StringBuilder script) { return script.toString().replaceAll("/\\*(.*?)\\*/", "").trim(); } 

есть ли чистый способ справиться с этим? есть ли что-то в спящем режиме, которого я не видел? или я могу каким-то образом передать входной поток в sqlplus? помимо моих забот о форматировании, я сомневаюсь, что этот код является безошибочным, так как у меня ограниченные знания о синтаксисе pl / sql.

Используйте ниже решение для вашей справки, я пробовал, тестировал и работал успешно.

 private static String script_location = ""; private static String file_extension = ".sql"; private static ProcessBuilder processBuilder =null; public static void main(String[] args) { try { File file = new File("C:/Script_folder"); File [] list_files= file.listFiles(new FileFilter() { public boolean accept(File f) { if (f.getName().toLowerCase().endsWith(file_extension)) return true; return false; } }); for (int i = 0; i<list_files.length;i++){ script_location = "@" + list_files[i].getAbsolutePath();//ORACLE processBuilder = new ProcessBuilder("sqlplus", "UserName/Password@database_name", script_location); //ORACLE //script_location = "-i" + list_files[i].getAbsolutePath(); // processBuilder = new ProcessBuilder("sqlplus", "-Udeep-Pdumbhead-Spc-de-deep\\sqlexpress-de_com",script_location); processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); String currentLine = null; while ((currentLine = in.readLine()) != null) { System.out.println(" " + currentLine); } } } catch (IOException e) { e.printStackTrace(); }catch(Exception ex){ ex.printStackTrace(); } } 

Используйте этот код фрагмента и попробуйте и запустите.

Thanx для пользователя упомянула решение в следующей ссылке:

http://forums.sun.com/thread.jspa?threadID=5413026

С уважением | Нитин

У iBATIS ScriptRunner есть setDelimiter(String, boolean) . Это позволяет вам иметь строку, отличную от ";" быть разделителем между операторами SQL.

В сценарии Oracle SQL отделите операторы с помощью «/» (косой черты).

В вашем Java-коде перед вызовом runScript выполните setDelimter("/", false) который даст указание ScriptRunner распознавать «/» как разделитель операторов.

Если бы такая же проблема была не так давно, она несколько раз сталкивалась с вашим вопросом, когда я искал решение, поэтому, думаю, я должен вам – вот мои выводы:

Короче говоря, для этого нет готовых решений: если вы откроете источники Ant или Maven , вы увидите, что они используют простой сплиттер сценариев на основе регулярного выражения, который подходит для простых скриптов, но обычно не выполняется, например, хранимых процедур. Такая же история с iBATIS, миграциями c5 db и т. Д.

Проблема в том, что существует несколько языков: для запуска «SQL-скриптов» необходимо иметь возможность обрабатывать (1) SQL, (2) PL / SQL и (3) команды sqlplus.

Запуск sqlplus сам по себе действительно так, но он создает беспорядок конфигурации, поэтому мы попытались избежать этой опции.

Есть ANTLR-парсеры для PL / SQL, такие как Alexandre Porcelli's one -those очень близки, но никто не подготовил полное решение для решения проблемы, основанного на тех, которые до сих пор.

Мы закончили писать еще один специальный разделитель, который знает о некоторых командах sqlplus, таких как / и EXIT – он все еще уродлив, но работает для большинства наших скриптов. (Обратите внимание, что некоторые скрипты, например, с трейлинг-комментариями, не будут работать – это все еще kludge, а не решение.)

sqlplus: да, вы можете. Я все время запускаю sqlplus из Xemacs (editor). Таким образом, вы можете запустить sqlplus в интерпретируемом режиме, а затем предоставить ему команды и прочитать результат.

Еще один способ – загрузить бесплатный инструмент разработки SQL на базе Java из oracle ( http://www.oracle.com/technology/software/products/sql/index.html ). он поставляется с утилитой sqlcli.bat, которая является оболочкой над java-программой. Вы можете использовать эту утилиту командной строки для выполнения своей работы.

резюме, я бы попытался запустить sqlplus в фоновом режиме и обеспечить его ввод и чтение его вывода (например, emacs).

Если вы хотите написать собственный сценарий, вы можете использовать SimpleJdbcTemplate Spring JDBC ( http://static.springframework.org/spring/docs/2.0.x/reference/jdbc.html ).

Конечно, вы можете загружать сценарии, как и любой ресурс в Spring.

Вы можете видеть реализации других людей. См. Этот ресурс: «SQL-клиенты с открытым исходным кодом на Java» http://java-source.net/open-source/sql-clients