Как сохранить файл XML в базе данных PL / SQL - PullRequest
7 голосов
/ 27 февраля 2020

Мне нужно сохранить текст файла XML, который я уже сохранил в местоположении FTP, в поле таблицы в базе данных, я использую пакет UTL_FILE для чтения файлов мне не очень понятно, как работает пакет, и я просто начинаю с топи c процедур в PL / SQL. Мой подход к дате:

  1. Используйте UTL_FILE.FOPEN, чтобы открыть файл.
  2. Создайте INSERT внутреннюю процедуру для хранения в поле базы данных

Для этого я выполняю процедуру в PL / SQL Я не знаю, правильно ли это для того, что мне требуется

    DECLARE

    l_bfile BFILE;
    l_clob CLOB;
    VFILE UTL_FILE.file_type;
    TEXT VARCHAR2(32767);
    L_CONN UTL_TCP.connection;
    P_CMTT_CODE SPRCMNT.SPRCMNT_CMTT_CODE%TYPE;
    P_TEXT      SPRCMNT.SPRCMNT_TEXT%TYPE;
    P_TEXT_NAR  SPRCMNT.SPRCMNT_TEXT_NAR%TYPE;

BEGIN

    L_CONN := FTP.LOGIN('000.00.000.00', '00', '*********', '*********');
    FTP.ASCII(P_CONN => L_CONN);
    FTP.GET(P_CONN => L_CONN, p_from_file => '/xml_file/ES0000251446027471.xml', p_to_dir => 'UPLOAD_DIR',  p_to_file => 'ES0000251446027471.xml');
    ftp.logout(l_conn);

    VFILE := UTL_FILE.fopen('UPLOAD_DIR', 'ES0000251446027471.xml', 'R', 4000);

    LOOP
        BEGIN
            UTL_FILE.GET_LINE(VFILE, TEXT, 32767);
            DBMS_OUTPUT.PUT_LINE(TEXT);
            INSERT INTO SPRCMNT (
                     SPRCMNT_PIDM,
                     SPRCMNT_CMTT_CODE,
                     SPRCMNT_TEXT,
                     SPRCMNT_TEXT_NAR,
                     SPRCMNT_ACTIVITY_DATE)
                            VALUES('15218',
                                   '15',
                                   P_TEXT,
                                   P_TEXT_NAR,
                                   SYSDATE)
                                   RETURN SPRCMNT_TEXT_NAR INTO l_clob;

         l_bfile := BFILENAME ('BAN_GUAUPLP_UPLOAD_DIR', 'ES0000251446027471.xml');
         dbms_lob.fileopen( l_bfile, dbms_lob.FILE_READONLY );
         dbms_lob.loadfromfile( l_clob, l_bfile, dbms_lob.getlength(l_bfile) );
         dbms_lob.fileclose( l_bfile );
         COMMIT;

         EXCEPTION 
            WHEN OTHERS THEN EXIT;
                   dbms_output.put_line('Error al cargar el archivo');  

        END;
    END LOOP;

    UTL_FILE.FCLOSE(VFILE);

END;

Где это P_CMTT_CODE собираемся сохранить по умолчанию значение 15, P_TEXT сохранить имя файла XML и P_TEXT_NAR все содержимое, я имею в виду все XML текст в таблице SPRCMNT

Я все еще не могу вставить весь текст XML в P_TEXT_NAR поле таблицы SPRCMNT.

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

Основная ошибка в том, что он не сохраняет XML имя и что файл XML содержит в соответствующих полях

enter image description here

ОБНОВЛЕНИЕ:

Тр y, чтобы сделать это с помощью функции BFILENAME, но во время вставки сохраните ее следующим образом, кроме того, она не сохраняет имя файла XML:

enter image description here

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Когда вы находитесь в среде и , вот решение и .

с учетом some.xml файла типа.

<?xml version="1.0"?>
<root>
<listitem someattribute='thingOne'>content One</listitem>
<listitem someattribute='thingTwo'>content Two</listitem>
<listitem someattribute='thingThree'>content Three</listitem>
</root>

и таблицы MYTABLE типа:

Name           Null?    Type               
-------------- -------- ------------------ 
COLUMNONE               VARCHAR2(25)         
COLUMNTWO               VARCHAR2(25)       

Я буду использовать скрипт PowerShell (xml2csv.ps1) например:

#read from file
[xml]$inputFile = Get-Content -Path some.xml

#Walk through the records
$inputFile.root.ChildNodes | 
    # re-map to column names using ScriptBlock(s)
    Select-Object @{Name=’columnOne’; Expression={$_.someattribute}},@{Name=’columnTwo’; Expression={$_.'#text'}} |
        # write out CSV file
        Export-Csv -Path some.csv -NoTypeInformation -Encoding:UTF8

Запустите это как powershell.exe xml2csv.ps1

Загрузите базу данных с помощью SQLcl (загрузить из https://www.oracle.com/tools/downloads/sqlcl-downloads.html или включить в SQL Developer) и выполните команду LOAD (https://www.thatjeffsmith.com/archive/2019/09/sqlcl-and-the-load-csv-command/).

Запустите сеанс sql.exe myuser/mypassword@MYDATABASE и выполните:

LOAD MYTABLE some.csv
1 голос
/ 27 февраля 2020

Хотя самый верный способ сделать это - отправить файл данных XML на сервер базы данных и использовать UTL_FILE для загрузки и обработки, используя нужные инструменты, которые вы можете go каким-то образом соединить с этим клиентом. / server gap.

Описанный ниже метод основан на использовании клиентских сценариев для создания сценария SQL* Plus, который инициализирует переменную CLOB с данными XML в анонимном блоке, что затем облегчает использование этого сценария. переменная SQL.

Пример ниже приведен в bash - если у вас установлена ​​bash или Cygwin на вашем клиенте (WIndows), или ваш клиент Linux / MacOS, это может помочь вы. Если нет, то, возможно, кто-то мог бы написать эквивалент DOS BAT / Powershell.

Идея состоит в том, чтобы создать скрипт с данными XML, представленными в виде переменной в анонимном блоке PL SQL, и затем передать их в хранимая процедура.

Вот сценарий bash the_script. sh:

XML_FILE=${1}   # File containing XML to load

SQL_SCRIPT=the_script.sql   # script we will construct to do the work

# Start constructing teh PLSQL blcok

cat <<EOF > ${SQL_SCRIPT}

declare
   vx_xml XMLTYPE;
   vc_xml CLOB ;
begin
   vc_xml := '';   
EOF

cat ${XML_FILE} | fold -80 -s | sed "s/^/      vc_xml := vc_xml || '/" | sed "s/$/';/" >> ${SQL_SCRIPT}


cat <<EOF >> ${SQL_SCRIPT}

   vx_xml := XMLTYPE(vc_xml);
   call_the_stored_proc(vx_xml); -- A strored procedure to process the XML data as required
end;
/

EOF

cat ${SQL_SCRIPT}

cat <<EOF > sqlplus -S /nolog

conn un/pw@db

@${SQL_SCRIPT}

quit

EOF

Выполните это следующим образом:

bash the_script.sh the_source_data.xml

...