Чтение из файла и помещение значений в предложение WHERE с помощью сценария оболочки - PullRequest
3 голосов
/ 22 октября 2010

Shell Script

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

Теперь цель - прочитать 32000 значений в столбце t2.value.Эти значения являются только числами, такими как 1234, 4567, 1236 и т. Д. Я предполагаю, что я должен поместить эти числа в отдельный файл и затем прочитать этот файл в t2.value.Но я хочу, чтобы SQL выполнялся только один раз, а не 32000 раз.Подскажите, пожалуйста, как это возможно?Как я могу получить значения (разделенные запятыми) в t2.value (по какому-то циклу, возможно, читая строку)?

Ответы [ 3 ]

1 голос
/ 22 октября 2010

вы можете использовать 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 голосов
/ 22 октября 2010
  #!/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 символов) - строка игнорируется.

Предыдущая ошибка, которую я получил, потому что я вставил числа в файл trnid, разделенные запятыми и в другую строку.В этом случае я использовал только команду:

 t2val=$(cat /home/trnid )
0 голосов
/ 22 октября 2010

Вы можете создать разделенный запятыми список из файла, который содержит все числа по одному в строке:

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

Далее вы можете использовать эту переменную $t2val как:

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

Мы заменяем \n между строками на запятую и удаляем последнюю запятую, которая не содержит следующего числа, поскольку это приведет к синтаксической ошибке в Oracle.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...