У меня есть небольшой веб-редактор SQL, но когда пользователь пишет запрос, как:
SELECT * FROM users;
SELECT * FROM references;| <-- here is the caret, i want to run only this query
SELECT * FROM settings
и отправить эту строку, только первый запрос выполняется. Я хочу выполнить только тот запрос, где расположена каретка пользователя.
Очевидно, этот пример выглядит легко, но рассмотрим более реалистичные запросы, используемые в реальной среде, что-то вроде:
SELECT col1,col2,col3
FROM users
WHERE id IN (1,2,3,4);
SELECT * FROM references WHERE status = 1
;
SELECT
a.col1
, a.col2
, b.col1
FROM table_a a | <--- Here is the caret, run this query
INNER JOIN table_b b ON b.id_table_a = a.id
WHERE a.id = 5
;
UPDATE table_a SET col1 = 'demo' WHERE id = 3;
-- etc, etc, etc
До сих пор у меня позиция каретки: row & столбец, и разрезать строку на две части: до каретки и после каретки.
Затем я получаю подстроку после появления последней точки с запятой в первой строке и подстроку перед появлением de first во второй строке.
Но я хочу знать, есть ли другие способы решить эту проблему с большей эффективностью.
Попробуйте регулярное выражение вроде этого:
/(?<=;)(.*)(?=\|)/
Для этого вы можете использовать подход регулярного или не регулярного выражения. Если ваши запросы будут содержать |
(трубы) в них, тогда было бы более целесообразно назначить другой / уникальный маркер.
Код: (демонстрация)
$queries="SELECT col1,col2,col3
FROM users
WHERE id IN (1,2,3,4);
SELECT * FROM references WHERE status = 1
;
SELECT
a.col1
, a.col2
, b.col1
FROM table_a a | <--- Here is the caret, run this query
INNER JOIN table_b b ON b.id_table_a = a.id
WHERE a.id = 5
;
UPDATE table_a SET col1 = 'demo' WHERE id = 3;
-- etc, etc, etc";
$rtrimmed=substr($queries,0,strpos($queries,'|')); // remove substr following pipe
$ltrimmed=substr($rtrimmed,strrpos($rtrimmed,';')+1); // remove substr upto latest semicolon
echo trim($ltrimmed); // remove whitespace on either side
echo "\n---\n";
echo preg_match('~;\s*\K[^;|]*?(?= *\|)~',$queries,$out) ? $out[0] : '';
Выход:
SELECT
a.col1
, a.col2
, b.col1
FROM table_a a
---
SELECT
a.col1
, a.col2
, b.col1
FROM table_a a
Разбивка паттернов:
~ #pattern delimiter
;\s* #match semicolon followed by zero or more whitespace characters
\K #restart the fullstring match (release previous matched characters)
[^;|]*? #match zero or more (lazily) non-semicolon and non-pipe characters
(?= *\|) #look ahead for zero or more spaces followed by a pipe (so that the output is trimmed)
~ #pattern delimiter