Фон
Я написал сценарий bash, который извлекает простые пользовательские функции из базы данных PostgreSQL, с помощью awk преобразует команды pgplsql в SQL (например, PERFORM function()
в SELECT function()
, удаляет комментарии --.*
и т. д.), сохраняет команды SQL в файл (file.sql
), считывает и выполняет их в базе:
$ psql ... -f file.sql db
Функции просты, в основном это просто вызов других пользовательских функций. Но как «оценить» или обработать оператор IF
?:
IF $1 = 'customer1' THEN -- THESE $1 MEANS ARGUMENT TO PGPL/SQL FUNCTION
PERFORM subfunction1($1); -- THAT THIS IF STATEMENT IS IN:
ELSE -- SELECT function('customer1');
PERFORM subfunction2($1); -- $1 = 'customer1'
END IF;
Tl;dr:
IF
s и тому подобное не являются SQL, поэтому их следует предварительно оценить с помощью awk. Можно с уверенностью предположить, что приведенное выше уже обработано в одну запись с удаленными комментариями:
IF $1 = 'customer1' THEN PERFORM subfunction1($1); ELSE PERFORM subfunction2($1); END IF;
После «оценки» выше следует заменить на:
SELECT subfunction1('customer1');
если awk для его оценки был вызван:
$ awk -v arg1="customer1' -f program.awk file.sql
или если arg1
что-то еще, например для customer2
:
SELECT subfunction2('customer2');
Изменить
expr
первое, что пришло мне в голову, когда я проснулся:
$ awk -v arg="'customer1'" '
{
gsub(/\$1/,arg) # replace func arg with string
n=split($0,a,"(IF|THEN|ELSE|ELSE?IF|END IF;)",seps) # seps to get ready for SQL CASE
if(seps[1]=="IF") {
# here should be while for ELSEIF
c="expr " a[2]; c|getline r; close(c) # use expr to solve
switch (r) { # expr has 4 return values
case "1": # match
print a[3]
break
case "0": # no match
print a[4]
break
default: # (*) see below
print r
exit # TODO
} } }' file.sql
(*) expr
выводит 0,1,2 или 3:
$ expr 1 = 1
1
$ expr 1 = 2
0
Однако, если вы опустите пробелы:
$ expr 1=1
1=1
psql
. Решения Postgres также приветствуются, но меня больше всего интересует awk atm. - person James Brown   schedule 25.04.2017IF $1 = 'customer1' THEN PERFORM subfunction1($1); ELSE PERFORM subfunction2($1); END IF;
, написанный на каком-то языке, и вы хотите написать awk-скрипт для разбора этого языка? Разве нет какого-то инструмента, который уже делает это? - person Ed Morton   schedule 25.04.2017IF
. - person James Brown   schedule 25.04.2017