从文件中读取并通过shell脚本将值放入WHERE子句中

时间:2010-10-22 05:35:29

标签: bash 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中获取值(以逗号分隔)(通过某个循环,可能是读取行)?

3 个答案:

答案 0 :(得分: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之后。

答案 1 :(得分:0)

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

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

接下来,您可以将此变量$t2val用作:

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

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

答案 2 :(得分: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 )