Подтвердить что ты не робот

Создайте ansi sql INSERT INTO

У меня есть база данных Oracle с 10 таблицами. В некоторых таблицах содержится текст данных CLOB. Мне нужно экспортировать данные из этих таблиц программно с помощью java. Данные экспорта должны быть в формате ANSI INSERT INTO SQL, например:

INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);

Основная идея заключается в том, что мне нужно импортировать эти данные в три разные базы данных: ORACLE, MSSQL и MySQL. Как я знаю, все эти базы данных поддерживают ANSI INSERT INTO. Но я не нашел java API/framework для генерации SQL-данных SQL. И я не знаю, как работать с данными CLOB, как его экспортировать.
Каков наилучший способ экспорта данных из базы данных с помощью java?

ОБНОВЛЕНИЕ: (01.07.2018)
Я думаю, что невозможно вставить текстовые данные более 4000 байт в соответствии с этим ответом. Как сгенерировать PL\SQL-скрипты с помощью java программно? Или есть какой-либо другой формат экспорта, который поддерживает ORACLE, MSSQL и т.д.?

4b9b3361

Ответ 1

Вы когда-нибудь думали о правильном ORM-Api? Первое, что в моих мыслях появилось бы в Hibernate или более абстрактном JPA/JPQL. Структура знает все основные диалекты sql. Все, что вам нужно, это определить ваши связи с вашими диалектами. Затем вы извлекаете данные из базы данных и сопоставляете их с POJO, а не вставляете данные в другое (другое диалектное) соединение. Должен работать хорошо, я думаю, даже если бы я никогда этого не делал. Но я знаю, что JPA не нова и широко используется ради изменения базы данных, даже когда программное обеспечение уже готово. Этот подход немного инперформат, так как каждая строка преобразуется в POJO, и есть, afaik, нет объемной вставки.

Ответ 2

Если вы ищете генерацию SQL, тогда доступно много библиотек sqlbuilder, которые вы можете использовать.

Вы можете использовать метаданные для получения имен столбцов и ввода из запроса select * и использовать его при вставке запроса.

См. https://github.com/jkrasnay/sqlbuilder

Подробнее об этом в http://john.krasnay.ca/2010/02/15/building-sql-in-java.html

Ответ 3

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

Это идеальный вариант использования JPA (Java Persistence API), который позволяет создать модель, которая представляет вашу структуру базы данных. Это решение для решения текущих задач Java для управления различными типами баз данных.

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

Итак, мое предложение, используя Spring Boot + Spring Data + Spring Batch:

  • Создайте первое приложение из вашей модели, которое экспортирует содержимое ваших таблиц в формат CSV.
  • Создайте второе приложение из той же модели, которая импортирует ваши CSV файлы. В зависимости от вас jdbc url, Spring Boot автоматически вызовет соответствующий диалект для вашей целевой базы данных и сгенерирует правильные запросы (это также относится к экспорту).

Это может быть сделано в течение разумного количества времени и с достойной производительностью.

Ответ 4

Мне нужно экспортировать данные из этих таблиц программно, используя java

Давай, парень! Что случилось? Java - это инструмент для работы с данными, а не для переноса. Если это касается ETL - используйте среды ETL целевой СУБД или напишите код ETL самостоятельно.

Ответ 5

Для MSSQL и ORACLE вы можете использовать синтаксис MERGE Tool (и предложение USING для Data) для стандартов ANSI:

MERGE INTO tablename USING table_reference ON (condition)
   WHEN MATCHED THEN
   UPDATE SET column1 = value1 [, column2 = value2 ...]
   WHEN NOT MATCHED THEN
   INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...]);

Для MySQL существует другой синтаксис (в заявлении о повторном ключевом ключе):

-- Insert new or merge into existing row.
MERGE INTO system_user target
USING (SELECT   1 AS system_user_id
       ,       'SYSADMIN' AS system_user_name
       ,        1 AS system_user_group_id
       ,        1 AS system_user_type
       ,       'Samuel' AS first_name
       ,        'the' AS middle_name
       ,       'Lamanite' AS last_name
       ,        1 AS created_by
       ,        SYSDATE AS creation_date
       ,        1 AS last_updated_by
       ,        SYSDATE AS last_update_date
       FROM     dual) SOURCE
ON (target.system_user_id = SOURCE.system_user_id)
WHEN MATCHED THEN
  UPDATE SET first_name = 'Samuel'
  ,          middle_name = 'the'
  ,          last_name = 'Lamanite'
  ,          last_updated_by = 1
  ,          last_update_date = SYSDATE
WHEN NOT MATCHED THEN
  INSERT
  ( target.system_user_id
  , target.system_user_name
  , target.system_user_group_id
  , target.system_user_type
  , target.first_name
  , target.middle_name
  , target.last_name
  , target.created_by
  , target.creation_date
  , target.last_updated_by
  , target.last_update_date )  
  VALUES
  ( SOURCE.system_user_id
  , SOURCE.system_user_name
  , SOURCE.system_user_group_id
  , SOURCE.system_user_type
  , SOURCE.first_name
  , SOURCE.middle_name
  , SOURCE.last_name
  , SOURCE.created_by
  , SOURCE.creation_date
  , SOURCE.last_updated_by
  , SOURCE.last_update_date );

и

-- Insert new or merge into existing row.
INSERT INTO system_user
( system_user_name
, system_user_group_id
, system_user_type
, first_name
, middle_name
, last_name
, created_by
, creation_date
, last_updated_by
, last_update_date )
VALUES
('SYSADMIN'
, 1
, 1
,'Samuel'
,'the'
,'Lamanite'
, 1
, NOW()
, 1
, NOW())
ON DUPLICATE KEY 
UPDATE first_name = 'Samuel'
,      middle_name = 'the'
,      last_name = 'Lamanite'
,      last_updated_by = 1
,      last_update_date = UTC_DATE();

Ответ 6

Я бы попробовал Scriptella. Является инструментом ETL с открытым исходным кодом и script, написанным на Java, на котором вы определяете в XML файле исходные и целевые соединения и преобразования, если это необходимо. Соединениями могут быть JDBC или даже текстовые файлы, а также функции поддержки пакетной обработки. Полученный xml файл может обрабатываться программно с помощью java, ant или командной строки.

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

Ответ 7

Мне очень нравится "про грамматически".:)

Лучший способ экспортировать эти данные - перебирать по таблицам, затем запрашивать каждый из них и выводить обычный текст с помощью операторов insert into. Это может быть проблемой, если у вас есть двоичные данные, поскольку разные RDBS могут иметь дело с ним несколько иначе.

Чтение blob/clob на стороне Java означает чтение потока. Он может быть двоичным или символьным. Для Oracle, от документ - вы можете сделать:

        ResultSet rs = s.executeQuery(
            "SELECT text FROM documents WHERE id = 1477");
        while (rs.next()) {
            java.sql.Clob aclob = rs.getClob(1);
            java.io.InputStream ip = rs.getAsciiStream(1);
            int c = ip.read();
            while (c > 0) {
                System.out.print((char)c);
                c = ip.read();
            }
            System.out.print("\n");
        }

Из этого ответа вы можете сделать это короче:

Clob clob = resultSet.getClob("CLOB_COLUMN")
String clob_content = clob.getSubString(1, (int) clob.length());

Написание вывода, возможно, потребует обработки: \t\n\r. Зависит от ваших потребностей, контента. Документы имеют полный пример - чтение, запись. Они используют подготовленный оператор, и поэтому потоки необходимы с обоих концов. Если ваш clob не большой - например 32k/64k, могут быть другие ограничения. Если у вас есть какой-то пример - например, create table с 2-3 строками, любому будет проще писать код и предоставлять что-то, что работает...