Вызов операторов sql в сценариях оболочки

Я работаю в среде Solaris, и я использую базу данных Oracle 10g.

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

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

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

    for i in * do cp $i /home/temp

2 . Создайте таблицу моментальных снимков (n): инициализируйте 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 " select max(value) from results_all " -- вывод максимального значения на консоль

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

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

-- увеличить m на 1

  1. Дождитесь журнала успеха

    хвост -f лог($m)* | -egrep "^УСПЕХ"

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

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

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

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

Спасибо,

Крис


person novice    schedule 08.10.2009    source источник
comment
Я не понимаю, в чем именно заключается ваш вопрос. Вы спрашиваете, как выполнять операторы sql из сценария оболочки?   -  person Juergen Hartelt    schedule 09.10.2009


Ответы (3)


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

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

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

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

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 имел одно и то же имя во всех таблицах. Сценарий можно изменить, чтобы изменить эти предположения, но дополнительные данные должны откуда-то поступать. Он может принадлежать входному файлу, и в этом случае вам нужно будет разметить прочитанные строки.

person APC    schedule 08.10.2009

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

person mob    schedule 08.10.2009
comment
Спасибо за предложение. единственный язык сценариев, с которым я отдаленно знаком, это оболочка. Спасибо, если вы можете расширить свои входные данные с учетом решения оболочки. - person novice; 08.10.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
person Sachin Chourasiya    schedule 07.12.2009