|
|
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
Всегда считал, что Oracle DB впереди планеты всей, но столкнулся с одним нюансом работы через jdbc, который почему то без проблем решается в PostgreSQL и MySQL, но при этом никак не могу найти способ сделать тоже самое в Oracle. В общем задача стандартная и распространенная, есть csv файл, который нужно максимально эффективно протолкнуть в БД. У MySQL это делается через jdbc конструкцией "LOAD DATA LOCAL INFILE 'С:\Temp\MyLocalCsvFileLocation.csv' INTO TABLE", ничего дополнительно на сервер тащить не нужно. У PostgreSQL это делается чуть сложнее, нужно за анврапить соединение, создать специфичный для драйвера PostgreSQL класс CopyManager и проделать тоже самое: Код: java 1. 2. 3. и точно так же ничего кроме jar'ника с драйвером не нужно. А вот у Oracle какая то беда, нужно вызывать внешнюю тулзу (sql*loader), которой нужен OCI клиент и т.д., как то некрасиво... Или может быть я не прав и можно точно так же, обойтись thin драйвером, состоящим из одного jar'ника? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.03.2017, 13:51 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
just_vladimir, если кратко - то нельзя. jdbc использует упрощенный протокол (без Direct Path Load). А sqlloader знает интерфейс OCI (нативный, не-JDBC). Грязный хак под названием Direct-Path-Load позволяет загружать сведения из *.csv файлов не по 1 строке а сразу целыми блоками прямо в datafiles. При этом мы кое-что теряем в удобстве. Не можем делать промежуточные commits и вставлять посторонние транзакции в другие таблицы. И есть еще нюасны с аллокацией экстентов. Поэтому на стороне java вы можете либо вызвать ProcessBuilder и передать ему "sqlldr ....." или можно поискать массу утилит загрузчиков из csv на java. Кажется у liquibase есть такая опция. Почитайте. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.03.2017, 23:13 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
just_vladimirВ общем задача стандартная и распространенная, есть csv файл, который нужно максимально эффективно протолкнуть в БД. вы работаете с веб проектами. Это гетерогенная среда, облака и ГУГЛ сервисы с распознаваниме речи и команд. Не надо "толкать" )) через драйвер. Используйте передачу файфла через многочисленные сервисы. ЗЫ Уже HTTP протокол ломают, а вы всё по старинке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 10:46 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
maytonПоэтому на стороне java вы можете либо вызвать ProcessBuilder и передать ему "sqlldr ....." Это то, чего бы очень хотелось избежать ... Просто удивляет, почему в MySQL и PostgreSQL соответствующий API предусмотрен в рамках jdbc драйвера, а в Oracle он запрятан во внешнюю утилиту... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 13:32 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
а что, один раз распарсить инсёрт с забинденными переменными, а дальще читать CSV построчно, резать на поля и скармливать инсерту - это неинтересно? все равно же надо прописывать мэппинг полей файла на поля таблицы. ну так на несколько строк больше писать? ....... но не ужасужасужас ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 15:18 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
just_vladimirЭто то, чего бы очень хотелось избежать ... Просто удивляет, почему в MySQL и PostgreSQL соответствующий API предусмотрен в рамках jdbc драйвера, а в Oracle он запрятан во внешнюю утилиту... Вообще-то, JDBC это стандарт. Хотелось бы увидеть ссылку на ту страницу __стандарта__ где это описано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 15:31 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
Вопрос в Java форуме почему в Oracle так, а не эдак? Ну, не написали они CSV импорт в рамках PL/SQL. Никто не мешает создать хранимку под собственные нужды. Либо вообще запускайте командную строку средствами Оракла. Решений масса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 15:40 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
На самом деле все там написали. Просто нужна правильная постановка задачи. Что вы хотите делать? Грузить файлы? ОК. Как часто? Какого размера? Как много средств вы готовы потратить на создание конфигурации? Забегая вперед я могу сказать что Oracle позволяет вообще не грузить данные а просто "примонтировать" csv файл как external table и уделать по скорости и МайСКЛ и ПостргреС. Это будет решением? Или это вас не устроит? А если не устроит - то смотрите то что я выше написал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 16:32 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
On 14.03.2017 13:32, just_vladimir wrote: > Это то, чего бы очень хотелось избежать ... Просто удивляет, почему в MySQL и PostgreSQL соответствующий API > предусмотрен в рамках jdbc драйвера, а в Oracle он запрятан во внешнюю утилиту... Есть же драйвера для чтения CSV, например: http://csvjdbc.sourceforge.net. Можно через него прочитать файл и через оракловый драйвер вставить данные в таблицу. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 16:49 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
BlazkowiczВопрос в Java форуме почему в Oracle так, а не эдак? Ну, не написали они CSV импорт в рамках PL/SQL. Никто не мешает создать хранимку под собственные нужды. Либо вообще запускайте командную строку средствами Оракла. Решений масса. А на вопрос в Oracle форуме был бы ответ, почему в вашем Java'овском драйвере ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 17:24 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
Denis PopovЕсть же драйвера для чтения CSV, например: http://csvjdbc.sourceforge.net. Можно через него прочитать файл и через оракловый драйвер вставить данные в таблицу. Где вы вообще такие решения находите ... Уж если и читать CSV, то через Apache Commons CSV ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 17:25 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
Leonid Kudryavtsevjust_vladimirЭто то, чего бы очень хотелось избежать ... Просто удивляет, почему в MySQL и PostgreSQL соответствующий API предусмотрен в рамках jdbc драйвера, а в Oracle он запрятан во внешнюю утилиту... Вообще-то, JDBC это стандарт. Хотелось бы увидеть ссылку на ту страницу __стандарта__ где это описано. Подождите, подождите, я где то написал, что такое описано в стандарте jdbc? Можно процитировать? Я писал о том, что разработчики MySQL и PostgreSQL позаботились пропилить нужную дырочку через jdbc драйвер, в которую можно слить файл для загрузки и это реально удобно, а вот в Oracle посчитали, что не надобно так делать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 17:28 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
maytonНа самом деле все там написали. Просто нужна правильная постановка задачи. Что вы хотите делать? Грузить файлы? ОК. Как часто? Какого размера? Как много средств вы готовы потратить на создание конфигурации? Забегая вперед я могу сказать что Oracle позволяет вообще не грузить данные а просто "примонтировать" csv файл как external table и уделать по скорости и МайСКЛ и ПостргреС. Это будет решением? Или это вас не устроит? А если не устроит - то смотрите то что я выше написал. external table - файло должно жить на том же самом сервере, что и сам Oracle, не вариант. Хочу обратить внимание, что нет проблемы стандартными средствами эффективно загрузить файл (прочитать Apache Commons CSV, потом вставить через addBatch/executeBatch, выполняя insert с хинтом /* +append */), есть проблема, что есть специально созданный для этих целей функционал и нет возможности им воспользоваться через jdbc. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 17:33 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
just_vladimirэффективно загрузить файл (прочитать Apache Commons CSV, потом вставить через addBatch/executeBatch, выполняя insert с хинтом /* +append */) Ты вообще понимешь как работает хинт "+append" ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 18:37 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
maytonjust_vladimirэффективно загрузить файл (прочитать Apache Commons CSV, потом вставить через addBatch/executeBatch, выполняя insert с хинтом /* +append */) Ты вообще понимешь как работает хинт "+append" ? А что не так ? Если верить I-net'у addBatch / executeBatch в Oracle JDBC порождают нормальный Bulk insert вызов SQL. Т.ч. весь пакет будет выполнен одной командой, соответственно append (если я правильно понимаю) уменьшит нагрузку на Redo и аллокацию. Если I-net не врет. Лично я бы доки Oracle перечитал. Другое дело, что кроме плюсов, append и минусы имеет. Огромные. Использованием append очень легко всю систему убить (наблюдал такое на реальной задаче в ERP системе) just_vladimirПодождите, подождите.... Тогда зачем вообще упоминать JDBC всуе ))) just_vladimirВ общем задача стандартная и распространенная, есть csv файл, который нужно максимально эффективно протолкнуть в БД. Ну Oracle дает 100500 способов это сделать. Зачем для решения этой задачи вообще Java ? Я могу назвать 100500 причин почему это делать не нужно. Но лучше это обсуждать за пивом, а не на Инет форуме. just_vladimirВ общем задача стандартная и распространенная... Ровно так же, как стандартная и распространеная задача - форматирования диска. А PostgreSQL и MySQL полный отстой, т.к. такой команды в JDBC не сделали ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 19:02 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
Leonid Kudryavtsevmaytonпропущено... Ты вообще понимешь как работает хинт "+append" ? А что не так ? Если верить I-net'у addBatch / executeBatch в Oracle JDBC порождают нормальный Bulk insert вызов SQL. Т.ч. весь пакет будет выполнен одной командой, соответственно append (если я правильно понимаю) уменьшит нагрузку на Redo и аллокацию. Если I-net не врет. Лично я бы доки Oracle перечитал. Другое дело, что кроме плюсов, append и минусы имеет. Огромные. Использованием append очень легко всю систему убить (наблюдал такое на реальной задаче в ERP системе) В твоей постановке хинт append будет бесполезен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 19:11 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
maytonВ твоей постановке хинт append будет бесполезен. Почему? В какой постановке и что значит полезен? Direct patch load, из плюсов, как минимум должно redo log уменьшится. Ну и минусов в реальной жизни полно. Т.ч. я бы не злоупотреблял. p.s. вроде не offtopic, напрямую с вопросом автора связано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 20:34 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
AFAIK Я бы сформулировал проблему в двух пунктах: 1) Приведет ли addBatch / executeBatch в Oracle JDBC к полноценному Array / bulk insert'у. Т.е. к передаче по сети и вставки всего пакета данных ОДНОЙ командой. Вроде да. http://oracle-internals.blogspot.ru/2012/09/plsql-bulk-insert-jdbc-batchexecute.html 2) Приведет ли использование хинта append в команде insert к direct path load'у ? В Inet-е встречается утверждение, что direct path только для конструкции INSERT from SELECT. Посмотрел доку, в http://docs.oracle.com/cd/B10501_01/server.920/a96540/statements_913a.htm#2063932 про это ни слово /но полно других ограничений/. В подфоруму Oracle утверждается, что есть некая терминологическая путаница. Bulk insert как обозначение для конкретной конструкции PL/SQL - при которой direct path НЕ работает. И bulk insert просто применительно к методу вставки многих данных за раз в SQL. Т.е. "bulk insert PL/SQL" директом не бывает, нужен INSERT from SELECT Но в SQL, просто INSERT /*+append*/ VALUES () вполне себе работает. Иначе как direct path load с клиента запускать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 21:03 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
Тема интересная. Но очень боянисто. В sql.ru/Oracle скорее всего уже обсуждалось. Автору мы ответ уже дали. Если он хочет быстро загрузить - то задействует нужные утилиты (в скобках замечу что точно также как и в PGSQL, MySQL). Если он (автор) просто капризничает или хочет птичьего молока - то пусть обосновывает почему на Java, почему скорости недостаточно и пусть приводит характеристики ETL-процесса. Сколько строк надо загрузить. Как часто e.t.c. Иначе разговор получается философский. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 21:29 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
повторюсь maytonТема интересная. Но очень боянисто. В sql.ru/Oracle скорее всего уже обсуждалось. В последние несколько лет периодически всплывает. При этом в "баянистом" виде ((( Но с другой стороны, тема важная /интеграция, обмен данных, performance/, нужная и наверное не простая /раз всплывает/ maytonв скобках замечу что точно также как и в PGSQL, MySQL Не совсем. CSV к SQL никакого отношения не имеет, поэтому в Oracle решается внешними утилитами. В Postgres это зачем-то реализовано на уровне ядра СУБД. Если кто считает по другому - просьба ссылку на стандарт ANSI SQL описывающий команды работы с CSV 1) Oracle JDBC нормально поддерживает array / bulk операции при insert. В том числе, поддерживает direct path load. Хотя в одной из прошлых тем, термин direct path load от Oracle участниками трактовался не однозначно. Что, и теоретически, и практически, позволяет на СТАНДАРТНОМ JDBC обеспечить функциональность и производительно близкую к специальным инструментам (sqlloader) http://www.sql.ru/forum/1245207/java-i-api-directpath-oracle 2) Postgre SQL array / bulk операции на вставку поддерживает через одно место. Максимум, может сцепить все команды в одну строчку. (вроде как и MySQL). Поэтому, для массовой вставки команда INSERT в PgSQL не годится как класс. Приходится использовать команду COPY, которая, командой SQL (в нормальном смысле этого слова) НЕ ЯВЛЯЕТСЯ. И специально для команды COPY изобретать "велосипед" как ей скармливать данные. Замечу, что при этом, создав сей велосипед, авторы не удосужились написать форматеры/парсеры для типов данных поддерживаемых PgSQL. И, даже, не описали форматы. В документации PgSQL для команды COPY в binary режиме просто написано - возьмите исходный код на C и посмотрите в нашем исходном коде ))) В общем, из за убожества PgSQL изобретен "велосипед": a) Команда COPY реализована на уровне ядра СУБД. Что, понятно, ни в каких стандартах SQL нет и любому стандарту SQL противоречит b) В драйверах сделан велосипед, позволяющий использовать велосипед из СУБД. Что, опять таки, никакого отношения к JDBC не имеет. В общем, от криворукости сотворили [мат вырезан] "дырочку" которая никаким образом к "задача стандартная и распространенная" не относится. Еще одна такая криворукость PgSQL - тип text / binary. То есть, она тоже может показаться удобной "дырочкой" ))) например не имеет ограничения 4000 как varchar2 в Oracle. Пока, в этой дырочке, что нибудь не застрянет ((( Note: жизненная мудрость. Есть что нибудь в дырочку не впихивается, это пол беды, всегда есть вазелин. А вот если там что нибудь застревает - это уже серьезно. Т.ч. перед тем как запихивать что нибудь сложно впихуемое, лучше подумать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2017, 22:23 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
Коллеги, а как Вы пакетами вставляли? Я то на перле по простому делал - размножал текст инсерта, с забинденными переменными, вставлял от между бегином - эндом, парсил а дальше - связывал последовательно и экзекьютил раз за разом. Ну на джаве бы все один в один бы повторил, а как еще можно? Код: perl 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.03.2017, 10:51 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.03.2017, 11:00 |
|
||
|
Можно ли вызвать sql*loader через jdbc ?
|
|||
|---|---|---|---|
|
#18+
Vladimir Baskakovсвязывал последовательно и экзекьютил раз за разом. Экзекьютить можно целиком пакет. В оптимале, весь пакет данных из многих строк БД пойдет на сервер одним сетевым round trip'ом. Первая ссылка из google (внимательно читать комментарии под статьей!): http://betteratoracle.com/notes/25-array-batch-inserts-with-jdbc ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.03.2017, 11:13 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39419143&tid=2123065]: |
0ms |
get settings: |
8ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
74ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
| others: | 232ms |
| total: | 409ms |

| 0 / 0 |
