2010-10-22 63 views
3

Shell脚本从文件,并把值仅在通过shell脚本条款

#! /bin/bash 
sqlplus -s <username>/<passwd>@dbname << EOF 
set echo on 
set pagesize 0 
set verify off 
set lines 32000 
set trimspool on 
set feedback off 
SELECT * 
    FROM <dbname>.<tablename1> tr 
    LEFT JOIN <tablename2> t2 ON t2.id2 = tr.id1 
    LEFT JOIN <tablename3> t3 ON t3.id2 = tr.id1 
    LEFT JOIN <tablename4> t4 ON t4.id2 = tr.id1 
WHERE tr.TIMESTAMP > SYSDATE - 75/1440 
    AND tr.TIMESTAMP <= SYSDATE - 15/1440 
    AND t2.value in (value1, value2, etc...) 
ORDER BY timestamp; 

exit; 
EOF 

现在,目的是在t2.value列读取32000个读取值。这些值只是像1234,4567,1236等数字我想我应该把这些数字在一个单独的文件,然后读取该文件在t2.value。但是我希望SQL只能执行一次,而不是32000次。你能告诉我这怎么可能?我怎样才能得到t2.value中的值(由逗号分隔)(通过一些循环,可能是阅读行)?

回答

0

您可以创建一个逗号分隔的列表从包含的每行的所有号码一个文件:

t2val=$(cat your_file_with_numbers | tr '\n' ',' | sed 's/,$//') 

接下来,您可以使用这个变量$t2val为:

.... 
and t2.value in ("$t2val") 

我们更换在带逗号的行之间使用\n,并删除最后一个逗号,因为它会在Oracle中创建语法错误。

+0

我在标准输出错误的错误: ORA-00972:标识符太长 – ErAB 2010-10-22 05:54:55

+0

ORA-00972来的时候,你已经使用了很长的标识符,> 38字符。但我们不会在任何地方更改任何标识符(列,表名)。你做了什么改变? – codaddict 2010-10-22 05:57:36

+0

我会粘贴完整的脚本。 – ErAB 2010-10-22 06:07:31

1

您可以使用SQL * Loader将这些值加载到您首次创建的临时表中,并在其唯一列上使用索引。

sqlldr user/password%@sid control=ctl_file 

内容的ctl_file

load data 
infile * 
append 
into table MY_TEMP_TABLE 
fields terminated by ";" optionally enclosed by '"' 
(
    column1 
) 
begindata 
"value1" 
"value2" 
[...] 

(双引号是可选的,不需要换号

然后修改您的查询:

AND t2 in (SELECT column1 FROM my_temp_table) 

DROP my_temp_table之后。

0
#!/bin/bash 
    2 t2val=$(cat /home/trnid | tr '\n' ',' | sed 's/,$//') 
    3 sqlplus -s <username>/<passwd>@dbname > /home/file << EOF 
    4 set echo on 
    5 set pagesize 0 
    6 set verify off 
    7 set lines 32000 
    8 set trimspool on 
    9 set feedback off 
10 SELECT * 
     FROM <dbname>.<tablename1> tr 
     LEFT JOIN <tablename2> t2 ON t2.id2 = tr.id1 
     LEFT JOIN <tablename3> t3 ON t3.id2 = tr.id1 
     LEFT JOIN <tablename4> t4 ON t4.id2 = tr.id1 
     WHERE tr.TIMESTAMP > SYSDATE - 75/1440 
     AND tr.TIMESTAMP <= SYSDATE - 15/1440 
     and t2.value in ("t2val") 
     order by timestamp; 
26 exit; 
27 EOF 

trnid file has total of 32000 lines (each number on separate line). The length of each number is 11 digits. 

我只是碰巧看到不同的错误:

输入截断为7499个字符 SP2-0027:输入太长(> 2499个字符) - 在线忽略 输入截断为7499个字符 SP2-0027 :输入过长(> 2499个字符) - 忽略行。

上一个错误我得到bcoz我插入数字在trnid文件中用逗号分隔,并在不同的行中。在这种情况下,我只使用命令:

t2val=$(cat /home/trnid)