Вызов SQL-операторов в сценариях оболочки - PullRequest
1 голос
/ 08 октября 2009

Я работаю в среде Solaris, а используемая БД - Oracle 10g.

Скелет того, что я пытаюсь;

Напишите скрипт ksh для выполнения следующего. Я понятия не имею как включить мой SQL-запрос в сценарий оболочки и цикл через заявления. Поэтому ниже приведено краткое изложение того, что я пытаюсь сделать.

  1. Копировать файл для обработки (по одному файлу за раз из списка 10 файлы в папке).

    для меня в * делать cp $ i / home / temp

2. Создайте таблицу моментальных снимков (n): Initialize n = 1

create table test insert account_no, balance from
records_all; 

- создает мою таблицу снимков и вставляет записи в SQL

  1. Проверка успешности создания таблицы:

select count(*) from snapshot1 - запросить номер записей в таблице - всегда фиксировано, скажем, в 400000

if( select count(*) from snapshot(n) = 400000 )
 echo " table creation successful.. proceed to the next step "
else
 echo " problem creating table, exiting the script .. "
  1. Если создание таблицы прошло успешно,

    echo «выбрать макс (значение) из results_all» - вывод максимального значения на консоль

  2. Обрабатывать мои файлы, используя следующие задания:

./runscript.ksh - READ -i $m (м - начальное значение 001) ./runscript.ksh - WRITE -i $m (м - начальное значение 001 - то же, что READ process_id)

- приращение m на 1

  1. Ждем успеха журнала

    tail -f log ($ m) * | -egrep "^ УСПЕХ"

  2. с шагом 1 до: Скопируйте файл 2 во временную папку; создать снимок (n + 1) таблицы

Выход, когда все файлы были скопированы для обработки.

done - Конец шага 1

Указатели на то, как заставить меня двигаться, будут очень ценными.

спасибо,

Kris

Ответы [ 3 ]

2 голосов
/ 08 октября 2009

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

Сначала вам понадобится кто-то с привилегией CREATE ANY DIRECTORY (вероятно, администратор БД) для создания объекта каталога:

create directory load_dir as '/home/temp'
/
grant read, write on directory load_dir to <your_user>
/

Следующий блок PL / SQL открывает файл и читает его. Для каждой строки в файле он создает таблицу, считает из нее и получает максимальное значение идентификатора.

declare
    fh_tabs utl_file.file_type;
    table_name varchar2(30);
    snapshot_name varchar2(30);
    stmt varchar2(4000) ;
    cnt_row pls_integer;
    cnt_tab pls_integer := 0;
    max_id pls_integer;
begin
    fh_tabs := utl_file.fopen('LOAD_DIR', 'file.name', 'R');
    << tables >>
    loop
        begin
            utl_file.get_line(fh_tabs, table_name);
            cnt_tab := cnt_tab + 1;
            snapshot_name := 'snapshot'||trim(to_char(cnt_tab));
            stmt := 'create table '||snapshot_name
                               ||' as select * from '||table_name;
            execute immediate stmt;
            execute immediate 'select count(*) from '
                               ||snapshot_name into cnt_row;
            dbms_output.put_line('New table '||snapshot_name||' has '
                               ||to_char(cnt_row)||' records.');
            execute immediate 'select max(id) from '
                               ||snapshot_name into max_id;
            dbms_output.put_line('Highest primary key = '||max_id);
        exception
            when no_data_found then
                utl_file.fclose(fh_tabs);
                dbms_output.put_line('End of file!. Tables created = '
                               ||to_char(cnt_tab));
                exit;
        end;
    end loop tables;
end;
/

Я предположил, что ваш файл не содержит ничего, кроме имен таблиц, и вы хотите, чтобы таблицы моментальных снимков имели одинаковое имя, а столбец ID имел одинаковое имя во всех таблицах. Сценарий можно изменить, чтобы изменить эти предположения, но дополнительные данные должны откуда-то поступать. Он может принадлежать входному файлу, и в этом случае вам потребуется токенизировать строки чтения.

1 голос
/ 08 октября 2009

Вот указатель: не пытайтесь делать это в оболочке. Вы можете вставить этот алгоритм в оболочку с кучей сильно экранированных выражений и каналов к клиенту вашей базы данных и обратно, но его будет трудно читать и поддерживать. Посмотрите на выполнение этой задачи с помощью некоторого языка сценариев или скомпилированного языка - Python, Perl, R, Java, C ++ - с пакетной поддержкой баз данных Oracle.

0 голосов
/ 07 декабря 2009

Есть два варианта, с которыми это может быть достигнуто.

  1. Создайте файл сценария sql и выполните его после правильного установления соединения с базой данных и
  2. Создайте здесь документ и выполните его с помощью sqlplus, подключившись к базе данных

1. Создайте файл сценария sql и выполните его после правильного установления соединения с базой данных

sql_file=sachin.sql
cat <<!SQL > $sql_file
    select $1 from dual;
    exit;
!SQL

sysdate=`sqlplus -s $ORACLE_LOGIN  @$sql_file 2>/dev/null  `
echo $sysdate
rm $sql_file

2 Создайте здесь документ и выполните его с помощью sqlplus

print "your query;
COMMIT;" > SQLS
cmd='sqlplus ${ORALOGIN} < SQLS >> sachin.log
eval $cmd
...