Inserir na tabela do Oracle em um loop

4

Requisito: Em um servidor em um diretório, vários arquivos estão presentes. Eu preciso ler os nomes dos arquivos e preencher em uma tabela do Oracle.

Eu escrevi o script assim, mas não está funcionando:

#!/bin/bash
names = find  /home/devuser -name 'BI*'
sqlplus -s  schema_name/passwd << EOF
for name in {names[@]}
do
insert into table1(file_name,status) values('$name','N'); done commit; exit

Está a transmitir DO INVALID IDENTIFIER .

    
por jagan 17.12.2013 / 09:50

2 respostas

3

for VARIABLE in 1 2 3 4 5 .. N
do
    command1
    command2
    commandN
done <<anything given here is taken as variable>>

Esta é a sintaxe básica e depois de done , o commit deve ser dado na próxima linha.

Portanto, o seu código deve ser.

#!/bin/bash
names = find  /home/devuser -name 'BI*'
sqlplus -s  schema_name/passwd << EOF
for name in {names[@]}
do
insert into table1(file_name,status) values('$name','N'); 
done 
commit; 
exit

Espero que ajude.

    
por 17.12.2013 / 10:02
3

Aqui está uma versão do script que funciona e corrige algumas coisas que você pode não ter considerado:

#!/bin/bash
(
    echo '-- some startup SQL*plus code'
    echo 'set echo off;'
    echo '-- etc'
    find /home/devuser -name 'BI*' -type f |
    awk -- '{
                gsub("7", "77", $0);
                printf("INSERT INTO table1(file_name,status) " \
                       "VALUES(7%s7, 7N7);\n", $0);
            }'

    echo 'COMMIT;'
) | sqlplus -s schema_name/passwd

Recursos:

  • Seleciona apenas arquivos ( -type f em find ) que correspondem ao glob 'BI * - veja a página de manual de find(1) para os diferentes tipos de arquivo disponíveis.
  • Escapa nomes de arquivos contendo aspas simples ('→' '), portanto a saída é SQL válida. 7 é o código ASCII octal da aspa simples, útil já que o código awk já está entre aspas simples.
  • Mais rápido que a expansão de backtick.
  • Deixe de fora a parte | sqlplus ... da última linha e você poderá ver o script SQL gerado.

Limitações:

  • Não funciona com nomes de arquivos contendo novas linhas ou outros caracteres não imprimíveis.
  • May não funciona com caracteres não-ASCII. Isso depende de vários fatores, alguns no lado do POSIX, alguns no lado do Oracle (e alguns provavelmente dentro do próprio SQL * plus).
  • Não é necessariamente o melhor caminho (pessoas melhores irão sem dúvida entrar em sintonia com suas versões).

A seção agrupada no início gera o script, incluindo um prólogo (útil para informar ao SQL * mais o que fazer com alguns dos recursos mais "agradáveis") e um epílogo para confirmar a transação.

O que há de errado com sua própria versão do script:

  • As atribuições são assim: VAR=foo . Não é VAR = foo (sim, é importante; o último tentará executar o comando VAR com argumentos = e foo , não executar uma atribuição de variável)
  • Se você quiser que $names expanda para os resultados do comando find , será necessário dizer names=$(find ...) ou names='find ...' , não names=find ... .
  • Qualquer coisa depois que o <<EOF for enviado para o SQL * Plus, o fragmento de script bash incluído (com o for loop) será interpretado pelo SQL * Plus, não pelo bash. Isso não é SQL válido, e o SQL * Plus naturalmente engasga com isso.
  • O corpo do loop for é uma instrução SQL, mas você espera que isso seja interpretado pelo bash, o que não está correto. Deve haver um echo antes da instrução SQL insert (e, claro, a coisa toda fora da seção <<EOF ).
  • Você deixou de fora o EOF em si. <<EOF significa "ler até que uma linha seja encontrada e comece com EOF ".
por 17.12.2013 / 11:43