Eu o resolvi usando perl ao invés de sed e usando a variável especial IRS (Input Record Separator - $ /) para processar linhas por ponto e vírgula, em vez de por nova linha.
Qualquer linguagem que suporte a mudança do IRS deve funcionar (provavelmente possível com o bash puro usando IFS=';'
, mas eu não explorei isso).
Neste exemplo, o perl carregará seu buffer até o separador de registro de entrada e processará todo esse conteúdo como uma linha - alterando o que é esse separador, você pode processar o arquivo uma instrução de cada vez, em vez de uma linha em um tempo. Então, posso corresponder ao padrão da (s) instrução (ões) em que estou interessado e anexar a lógica das linhas afetadas à linha antes de ser impressa.
$ cat test.sql
SELECT non-matching-statement FROM table;
MERGE INTO employees e
USING hr_records h
ON (e.id = h.emp_id)
WHEN MATCHED THEN
UPDATE SET e.address = h.address
WHEN NOT MATCHED THEN
INSERT (id, address)
VALUES (h.emp_id, h.address);
SELECT another-non-matching-statement FROM table;
end;
$ cat test.sql | perl -pe 'BEGIN{$/=";"} m/MERGE INTO .*/ && ($_ .= "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL %ROWCOUNT;")'
SELECT non-matching-statement FROM table;
MERGE INTO employees e
USING hr_records h
ON (e.id = h.emp_id)
WHEN MATCHED THEN
UPDATE SET e.address = h.address
WHEN NOT MATCHED THEN
INSERT (id, address)
VALUES (h.emp_id, h.address);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
SELECT another-non-matching-statement FROM table;
end;
$
Usando menos abreviações por perl, você pode fazer isso:
perl -e '$/=";"; foreach $statement (<>){ print $statement; $statement =~ m/(MERGE INTO .*)|(DELETE FROM)/i && print "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;" }'
por exemplo:
cat test.sql | perl -e '$/=";"; foreach $statement (<>){ print $statement; $statement =~ m/(MERGE INTO .*)|(DELETE FROM)/i && print "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;" }'
SELECT non-matching-statement FROM table;
MERGE INTO employees e
USING hr_records h
ON (e.id = h.emp_id)
WHEN MATCHED THEN
UPDATE SET e.address = h.address
WHEN NOT MATCHED THEN
INSERT (id, address)
VALUES (h.emp_id, h.address);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
SELECT another-non-matching-statement FROM table;
DELETE FROM truncate_me;
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
end;
$