Создание CSV-файла для цикла | PLSQL Разработчик Oracle SQL

Обновлено

Рад-люди!

TL;DR

Нужен рабочий код для циклического просмотра существующего списка всех моих таблиц, который создаст файлы CSV, выбирая 100 первых строк каждой таблицы. Существуют переменные, настроенные для захвата имен таблиц, которые будут использоваться для динамического вызова таблицы для выбора и присвоения имени файлу. Необходимо делать через PLSQL и SQLDeveloper. Ты знаешь да вае?

Вот ситуация:

  • Необходимо собрать все таблицы (базовые таблицы не являются временными) и количество строк (количество строк > 0)
  • Создайте цикл для выбора (*) первых 100 строк из списка таблиц.
  • Возьмите результат запроса и поместите его в файл CSV.

Проблемы:

  • Объявление переменных
  • Использование начала и конца
  • Использование динамического имени для создания уникальных файлов CSV

Вот мой код:

CREATE GLOBAL TEMPORARY TABLE NameRow (nom VARCHAR2(100), rowc INTEGER)
  on commit delete ROWS;
  insert into NameRow(nom, rowc) select table_name, num_rows from user_tables where temporary = 'N' and num_rows > 0;
    --select * from namerow;
    --select count(nom) from namerow;
    --drop table namerow;
    --no need for the row count > 0 because that was already done above
 declare
  counter number := 0;
  totalrecords number := 0;
  nmbre varchar2(100);
 BEGIN

    Select count(nom) into totalrecords from namerow;
    WHILE counter <= totalrecords LOOP
      select nom into nmbre from NameRow where rownum =1;
    SET SPOOL ON
    SPOOL c:\Users\l.r.enchaustegui\Documents\reporepo\||nmbre||.csv
    select /*csv*/ * from HR.nmbre;
    SET SPOOL OFF 
        delete from namerow where rownum=1;
        counter := counter + 1;
    End loop;
 END;

Объяснение кода:

  • Создается временная таблица с столбцом varchare и integer для записи всех таблиц в БД с их RowCount.
  • Имена таблиц, вставленные во временную таблицу, не должны быть временными и содержать более 0 строк.

Следующий сегмент

  • Объявление 3 переменных: 2 целых числа и varchar
  • 2 целых числа: 1 — счетчик цикла. 1 записывает общее количество строк в таблице Temp, которые будут служить максимальным числом итераций в цикле.
  • Varchar: Nmbre запишет имя первой таблицы во временной таблице.

Следующий сегмент

  • Буфер по следующему пути, используя переменную Nmbre для динамического присвоения имени CSV-файлу.
  • Spool Query с использованием переменной Nmbre для динамического выбора таблицы
  • Удалить 1-ю строку из временной таблицы [служит для перехода к следующему имени таблицы]
  • Катушка выключена
  • Петля
  • Конечная петля; Конец;

Где я не прав? Кроме того, я получаю эту ошибку:

Бонусный раунд: Ограничено разработчиком SQL


person ThereIsLeo    schedule 20.02.2018    source источник
comment
Можете ли вы использовать SQLcl, который является ядром sqldev, в качестве строки cmd?   -  person Kris Rice    schedule 20.02.2018
comment
Вы не можете вставлять команды sqlplus, встроенные в инструкцию sql. Другой вариант — использовать UTL_FILE для файлового ввода-вывода, но в этом случае файлы создаются на сервере, а не на вашей рабочей станции.   -  person OldProgrammer    schedule 20.02.2018
comment
@KrisRice Я уверен, что смогу. Какой обходной путь вы видели?   -  person ThereIsLeo    schedule 20.02.2018
comment
@OldProgrammer Прошу прощения, я новичок в PLSQL, какие команды SQLPLUS я встроил? Как вы представляете решение, использующее UTL_FILE?   -  person ThereIsLeo    schedule 20.02.2018
comment
Это домашнее задание?   -  person Stilgar    schedule 20.02.2018
comment
Команды буферизации — это SQL*Plus.   -  person William Robertson    schedule 20.02.2018
comment
с sqlcl вы можете немного больше сочетать. В противном случае, поскольку @OldProgrammer у вас есть смешанный код клиента в plsql, это не сработает.   -  person Kris Rice    schedule 20.02.2018
comment
@Stilgar, это минус. Выполнение легкой (грязной) работы в команде, выполняющей ETL. Я довольно новичок в PLSQL и исчерпал много ресурсов, пытаясь решить эту загадку.   -  person ThereIsLeo    schedule 20.02.2018
comment
Я до сих пор не могу решить эту проблему. :(   -  person ThereIsLeo    schedule 21.02.2018


Ответы (1)


Вот вариант с использованием SQLcl. SQLcl — это внутренности SQLDEV, но завернутые в строку cmd. Также, будучи java, доступны возможности сценариев ядра java. Это использует JavaScript в качестве механизма сценариев.

У нас есть некоторый документ и множество примеров того, как все это работает на github, здесь: https://github.com/oracle/oracle-db-tools/tree/master/sqlcl

script
 var binds = {};

// get complete list of tables
 var tables = util.executeReturnList("select table_name from user_tables", binds);

 for (i = 0; i < tables.length; i++) {
   // get count of rows
    var rows = util.executeReturnOneCol('select count(1)  from ' +  tables[i].TABLE_NAME );
    ctx.write( tables[i].TABLE_NAME + ">>"  + rows + " \n" ) ;

    // if more than zero dump to a csv file
    if ( rows > 0 ){
        sqlcl.setStmt("set sqlformat csv ")
        sqlcl.run();
        sqlcl.setStmt("spool " + tables[i].TABLE_NAME + ".csv")
        sqlcl.run();

        sqlcl.setStmt("select * from  " + tables[i].TABLE_NAME )
        sqlcl.run();
        sqlcl.setStmt("spool off")
        sqlcl.run();

    }
 }
/
person Kris Rice    schedule 20.02.2018
comment
Спасибо, Крис, я постараюсь обдумать это. - person ThereIsLeo; 21.02.2018
comment
Конечно. Это отличается тем более, что добавление клиентского потока управления является серьезным изменением по сравнению со 100% PLSQL. - person Kris Rice; 21.02.2018
comment
Несмотря на мою нынешнюю некомпетентность, спасибо за ваш вклад! - person ThereIsLeo; 21.02.2018
comment
Вот для чего мы здесь :) - person Kris Rice; 21.02.2018