Как добавить точки с запятой в SQL-запросы?

Скажем, у меня есть это (с форматом, который я показываю, без новых строк)

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)

Я хочу, чтобы вывод был

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);

Чтобы это были легитимные SQL-запросы. Я пробовал это в sed:

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

Что работает, за исключением случаев, когда внутри значений есть парантезы, я не уверен, что нужно сделать, чтобы исправить это. По сути, я хочу добавить точку с запятой в конец (.*), (последний )), если перед ним написано VALUES.

0
05.09.2016, 15:18
3 ответа

Вы можете решить проблему, сопоставив другую часть оператора, например,

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

Это не будет зависеть от того, что находится внутри круглых скобок.

0
28.01.2020, 04:50

Нет простого шаблона, который был бы верным в любых обстоятельствах; вам нужно будет написать синтаксический анализатор SQL, чтобы определить, когда конец оператора должен быть ... и даже тогда вам нужно будет надеяться, что не произойдет никакого особого волшебства. Теперь ANSI SQL не является полным по Тьюрингу (хотя могут быть и расширения), поэтому вы, вероятно, могли бы написать синтаксический анализатор ...

Или вы могли бы написать синтаксический анализатор на основе стека, чтобы добавить ; после закрытия ) ... и обрабатывать неверный синтаксис.

Вместо этого вы можете использовать что-то, что с большей вероятностью не совпадет с ошибками. Например, этот код берет оператор INSERT INTO и помещает перед ним ; , не забывая добавить его в самом конце.

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

Очевидно, это не удалось бы, если бы во вставленных данных была эта конкретная строка ...

0
28.01.2020, 04:50

1) Предполагая, что окончание ) из VALUES будет сопровождаться ключевым словом INSERT или концом строки, как указано в примере ввода, предоставленном в вопросе

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

2) Предполагается, что существует два способа ЗНАЧЕНИЯ могут присутствовать:

  • ЗНАЧЕНИЯ без внутреннего () не будут иметь в себе '
  • ЗНАЧЕНИЯ с внутренним () будут начинаются как (' и заканчиваются на ')

perl -pe "s/VALUES\s*\([^')]*\)/$&;/g ; s/VALUES\s*\('.*?'\)/$&;/g" file
0
28.01.2020, 04:50

Теги

Похожие вопросы