Como adiciono ponto e vírgula às instruções SQL?

0

Digamos que eu tenha isso (com o formato que eu mostro, sem novas linhas)

INSERT INTO 'somthing' ('something') VALUES (1) INSERT INTO 'somthing' ('somethingelse') VALUES ('something with a (paranthesis) in it') INSERT INTO 'somthing' ('something') VALUES (3) INSERT INTO 'somthing' ('something') VALUES (4)

Eu quero que a saída seja

INSERT INTO 'somthing' ('something') VALUES (1); INSERT INTO 'somthing' ('somethingelse') VALUES ('something with a (paranthesis) in it'); INSERT INTO 'somthing' ('something') VALUES (3); INSERT INTO 'somthing' ('something') VALUES (4);

Para que eles sejam legítimas consultas SQL. Eu tentei isso em sed:

sed 's/\(VALUES ([^)]*)\)/;/g')

O que funciona, exceto quando há parantheses dentro dos valores, não sei o que fazer para corrigir isso. Basicamente, eu quero adicionar um ponto-e-vírgula ao final de (.*) , (o último ) ) se ele diz VALUES antes.

    
por Josef Djur 05.09.2016 / 02:16

3 respostas

0

Não há um padrão simples que seja correto em todas as circunstâncias; você precisaria escrever um analisador SQL para determinar quando o fim da instrução deveria ser ... e mesmo assim você precisaria esperar que não houvesse mágica especial acontecendo. Agora ANSI SQL não é Turing Complete (embora extensões possam ser) então você provavelmente poderia escrever um analisador ...

Ou você pode escrever um analisador baseado em pilha para adicionar um ; após um fechamento de ) ... e lidar com uma sintaxe incorreta.

Em vez disso, você pode querer usar algo mais provável para não corresponder erroneamente. Por exemplo, esse código pega na instrução INSERT INTO e coloca um ; na frente disso, lembrando de adicionar um no final.

sed -e 's/\( INSERT INTO 'somthing' ('something') VALUES (\)/;/g' -e 's/$/;/'

Obviamente, falharia se os dados inseridos tivessem essa string específica ...

    
por 05.09.2016 / 02:36
0

Você pode resolver o problema combinando uma parte diferente da declaração, por exemplo,

sed -e 's/\(VALUES ('[^']*')\)/;/g' \
    -e "s/\(VALUES ('[^']*')\)/;/g" \
    -e 's/\(VALUES ([0-9]*)\)/;/g'

Isso não depende do que está dentro dos parênteses.

    
por 05.09.2016 / 02:32
0

1) Assumindo que o final ) de VALUES será seguido por INSERT palavra-chave ou fim de linha, conforme fornecido na entrada de amostra fornecida na pergunta

perl -pe 's/VALUES\s*\(.*?\)(?=\s*INSERT|$)/$&;/g' file

2) Supondo que existem duas maneiras em que VALUES pode estar presente:

  • VALORES sem interior () não terão ' neles
  • VALUES com () interno começarão como (' e terminarão com ')

perl -pe "s/VALUES\s*\([^')]*\)/$&;/g ; s/VALUES\s*\('.*?'\)/$&;/g" file
    
por 05.09.2016 / 05:13