【问题标题】:Insert one table and update another with shellscript插入一个表并使用 shell 脚本更新另一个表
【发布时间】:2016-05-21 10:02:39
【问题描述】:

我的 shell 脚本有问题。我想将数据从文件插入到 table1(空),然后将 table1 与 table2 进行比较并更新一些字段。

第一部分是正确的,但第二部分不起作用。 它起作用的唯一方法是,如果在第一部分之后我截断 table1 并再次运行脚本。

我想一次完成所有事情(插入数据并更新)

我的脚本:

    #!/bin/ksh    
DATE=`date +"%Y%m%d"`
PATH_LD=$HOME/myscripts/script_anuk
    PATH_BIN=$HOME/bin/myscripts/script_anuk
    PATH_LOG=$HOME/log/myscripts/script_anuk


    logfile=$PATH_LOG/script_anuk$FECHA.log
    logfileMod=$PATH_LOG/script_anuk_mod$FECHA.log

    # Insert 

    sqlldr parfile=$PATH_LD/script_anuk_param.par USERID=$CONSQLPLUS

    # Update
      sqlplus -s $CONSQLPLUS << EOF!

     SET SERVEROUTPUT ON

     SET FEEDBACK OFF
    exec declare cursor d1 is select d.book, d.phone,d.pencil from table1 d,table2 n where d.book = n.book; whow number:=0;begin for r1 in d1 loop update table2 set phone=r1.phone,pencil=r1.pencil where book = r1.book; whow := whow + 1;if mod(whow,10000) = 0 then commit; end if;end loop;end;
    exit
    EOF!

我的.par

Par
USERID=/
CONTROL=$HOME/myscripts/script_anuk/script_anuk_param.ctl
DATA=$HOME/myscripts/script_anuk/data1.dat
LOG=$HOME/log/myscripts/script_anuk/script_anuk_param.log
BAD=$HOME/myscripts/script_anuk/error/script_anuk_param.bad
DISCARD=$HOME/myscripts/script_anuk/error/script_anuk_param.dsc
ERRORS=1000000
ROWS=500
DIRECT=FALSE

我的 .ctl

Ctl
LOAD DATA
INFILE *
INTO TABLE table1
APPEND
FIELDS TERMINATED BY ';'
(book  , 
phone         ,
pencil)
)

你能帮帮我吗?谢谢! :)

【问题讨论】:

  • 您会遇到什么样的错误(如果有)?只是没有更新行吗? table1 和 table2 有多少行?你有没有达到你的提交点/计数?尝试验证您是否达到了提交点 (10000)。
  • 只是没有更新任何行。表 1 - 50.000 条记录。表 2 - 350.000 条记录
  • 您是否尝试过自己运行 sqlldr 部分,然后在 SQL*Plus 中单独运行匿名 PL/SQL 块以查看是否出现任何错误?

标签: oracle shell unix plsql sh


【解决方案1】:

我正在查看您的匿名块,并通过 SQL*Plus 会话成功运行它:

  1  declare
  2        cursor d1 is
  3        select d.book, d.phone,d.pencil
  4        from table1 d,table2 n
  5        where d.book = n.book;
  6  
  7        whow number:=0;
  8        begin
  9          for r1 in d1 loop
 10            update table2
 11            set phone=r1.phone,
 12                pencil=r1.pencil
 13            where book = r1.book;
 14  
 15          whow := whow + 1;
 16          if mod(whow,10000) = 0 then
 17            commit;
 18          end if;
 19       end loop;
 20       commit;
 21       end;
 22  /

注意我没有在declare 之前调用exec,我在末尾添加了一个commit 以确保在退出之前提交所有行,并且我需要一个/ 来完成和执行该块。我认为这是您遇到的问题的症结所在。

您可能还希望将 STDOUT 和 STDERR 重定向到一个文件,以捕获 SQL*Plus 会话信息。尝试将您的 sqlplus 行更改为:

sqlplus -s $CONSQLPLUS >>$logfile 2>&1 << EOF!

这不是必需的,但可以帮助您解决问题。

【讨论】:

  • OP 的代码看起来不错;我不会为此使用exec,因为它阻止您将代码拆分为多行,但它仍然有效。如果删除 exec,则只需要 /。 SQL*Plus 在退出时也会提交,尽管再次明确地这样做会更清楚。所以虽然这看起来更好,并且可以嵌入到heredoc中,但我认为这不是问题的症结。
  • 好点@Alex Poole。在“提交”时,我想确保它已完成,因为它可以在 Oracle 11g 中使用 SET EXITCOMMIT OFF 在 $ORACLE_HOME/sqlplus/admin/glogin.sql 文件中被覆盖。
  • 是的,而且肯定不会造成伤害;尽管他们说没有更新任何行,而不仅仅是上次迭代的那些。虽然不太清楚发生了什么。
  • @Alex Poole 完全同意你的看法。目前尚不清楚这里发生了什么。有人会认为 SQL*Plus 会话会引发某种错误。感谢您的反馈意见。干杯!
【解决方案2】:

这是数据

drop table table1;
drop table table2;
create table table1 (book varchar2(5), phone varchar2(10), pencil varchar2(10));
create table table2 (book varchar2(5), phone varchar2(10), pencil varchar2(10));
insert into table1 values ('Book1','Phone1','Pencil1');
insert into table1 values ('Book2','Phone2','Pencil2');
insert into table2 values ('Book1','Phone1','oops');
insert into table2 values ('Book3','Phone3','Pencil3');
commit;

select * from table1;

BOOK  PHONE      PENCIL   
----- ---------- ----------
Book1 Phone1     Pencil1   
Book2 Phone2     Pencil2   

select * from table2;

BOOK  PHONE      PENCIL   
----- ---------- ----------
Book1 Phone1     oops      
Book3 Phone3     Pencil3   

如果 BOOK 在两个表中都是唯一的,那么您可以改为在脚本中执行此操作

update table2 t2
set (phone, pencil) = 
  (select t1.phone, t1.pencil
  from table1 t1
  where t1.book = t2.book)
;

注意 - 如果 BOOK 不是主键或唯一键,那么只要 t1 中有 >1 行与 BOOK 上的 t2 中的行匹配,此更新就会失败并出现错误。

【讨论】:

  • 谢谢,但我需要来自 .par 的数据,我需要一个游标(提交 10000 条记录)
猜你喜欢
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多