2016-05-21 68 views
0

我的shell脚本有问题。我想从文件中插入数据到table1(空),然后比较table1和table2并更新一些字段。插入一张表并用shellscript更新另一张表

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

我想在一个时间一切(数据插入和更新)

我的shell:

#!/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) 
) 

可以哟你能帮我吗?谢谢! :)

+0

你会得到什么样的错误,如果有的话?仅仅是没有行更新? table1和table2中有多少行?你有没有达到你的提交点/数量?尝试验证您是否达到了您的提交点(10000)。 – tale852150

+0

只是没有行被更新。表1 - 50.000记录。 Table2 - 350.000记录 –

+0

您是否曾尝试单独运行sqlldr部分,然后在SQL * Plus中单独运行匿名PL/SQL块以查看是否发生错误? – tale852150

回答

0

我在看你的匿名块,我顺利通过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! 

这不是必需的,但可能有助于解决您的问题。

+0

OP的代码看起来不错;我不会使用'exec',因为它会阻止你将代码分成多行,但它仍然有效。如果你删除了'exec',你只需要'/'。另外,SQL \ * Plus会在退出时提交,不过再次明确地做得更清楚。因此,虽然这看起来更好,可以嵌入到heredoc中,但我认为这不是问题的关键。 –

+0

好点@Alex Poole。在“提交”时,我想确保它已完成,因为可以在Oracle 11g中的SET EXITCOMMIT OFF的$ ORACLE_HOME/sqlplus/admin/glogin.sql文件中覆盖它。 – tale852150

+0

是的,当然也不会伤害到;尽管他们说没有行更新,而不仅仅是最后一次迭代的行。不太清楚发生了什么事情。 –

0

下面是数据

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 

如果书是唯一两个表中,那么你可以在你的脚本,而不是

做到这一点
update table2 t2 
set (phone, pencil) = 
    (select t1.phone, t1.pencil 
    from table1 t1 
    where t1.book = t2.book) 
; 

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

+0

谢谢,但我需要.par中的数据,我需要一个游标(提交10000个récords) –

相关问题