1

我正在开发 Solaris 环境,我使用的数据库是 Oracle 10g。

我正在尝试的骨架;

编写一个 ksh 脚本来执行以下操作。我不知道如何在 shell 脚本中包含我的 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 结束

让我动起来的指针将非常有价值。

谢谢,

克里斯

4

3 回答 3

2

碰巧我刚刚在现实生活中做了类似的事情。所以这里是一个纯 SQL 的解决方案。

首先,您需要有CREATE ANY DIRECTORY特权的人(可能是 DBA)来创建目录对象:

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 列在所有表上具有相同的名称。可以修改脚本以更改这些假设,但附加数据必须来自某个地方。它可能属于输入文件,在这种情况下,您需要对读取的行进行标记。

于 2009-10-08T08:20:49.670 回答
1

这是一个指针:不要尝试在 shell 中执行此操作。您可以使用大量转义表达式和进出数据库客户端的管道将这个算法硬塞到 shell 中,但它很难阅读并且难以维护。考虑使用一些脚本或编译语言(Python、Perl、R、Java、C++)执行此任务,并打包支持 Oracle 数据库。

于 2009-10-08T03:44:25.430 回答
0

有两种选择可以实现。

  1. 创建一个 sql 脚本文件并在正确建立与数据库的连接后执行它,并且
  2. 创建here文档并通过连接数据库使用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 创建here文档并用sqlplus执行

print "your query;
COMMIT;" > SQLS
cmd='sqlplus ${ORALOGIN} < SQLS >> sachin.log
eval $cmd
于 2009-12-07T11:09:59.443 回答