Regex для парсинга параметров SQL

Вот очень упрощенный пример, в котором я определяю количество ожидаемых платежей и количество месяцев, в течение которых был произведен платеж - если не совпадает, то мне интересно

drop table if exists u,t;
create table u (id int,subs int, dt date);
create table t (uid int,dt date);
insert into u values (1,1,'2019-01-01'),(2,1,'2018-11-01'),(3,1,'2018-09-01');
insert into t values
(1,'2019-01-01'),
(2,'2018-11-11'),(2,'2018-11-13'),(2,'2019-01-01');



select id,
        ((year(now()) * 12 + month(Now())) -  (year(u.dt) * 12 + month(u.dt))) + 1 numexpected,
        coalesce(s.paidup,0) paidup
from u
left join
(select t.uid,count(distinct year(t.dt),month(t.dt)) paidup
from t
group by t.uid) s on s.uid = u.id
where ((year(now()) * 12 + month(Now())) -  (year(u.dt) * 12 + month(u.dt))) + 1 <> coalesce(s.paidup,0);

+------+-------------+--------+
| id   | numexpected | paidup |
+------+-------------+--------+
|    2 |           3 |      2 |
|    3 |           5 |      0 |
+------+-------------+--------+
2 rows in set (0.00 sec)

Обратите внимание на ожидание Платеж, который должен производиться каждый месяц, кажется немного упрощенным - как насчет предоплат и поздних платежей? Например, UID 2 сделал 3 платежа, но 2 были в том же месяце.

6
задан bluish 11 November 2011 в 13:42
поделиться

2 ответа

Учитывая Вас не имеют никаких заключенных в кавычки строк или комментариев с параметрами в них, необходимый regex был бы довольно тривиален:

@([_a-zA-Z]+)       /* match group 1 contains the name only */

Я иду с рекомендацией Bill Karwin быть осторожным, зная, что наивный подход имеет свои ловушки. Но если бы Вы kow, данные, Вы имеете дело с, этот regex, были бы всем, которое Вам нужно.

4
ответ дан 8 December 2019 в 18:43
поделиться

Это хитро, потому что параметрические усилители могут также произойти в заключенных в кавычки строках.

SELECT * FROM authors WHERE name = @name_param 
  AND string = 'don\'t use @name_param';

Как регулярное выражение знало бы для использования первого @name_param но не второе?

Это - проблема, которая может быть решена, но это не практично, чтобы сделать это в единственном регулярном выражении. Я должен был обработать это в Zend_Db, и что я сделал была первая полоса все заключенные в кавычки строки и выделенные идентификаторы, и затем можно использовать регулярные выражения на остатке.

Вы видите код, потому что это - открытый исходный код. Посмотрите функции _stripQuoted() и _parseParameters().

https://github.com/zendframework/zf1/blob/136735e776f520b081cd374012852cb88cef9a88/library/Zend/Db/Statement.php#L200 https://github.com/zendframework/zf1/blob/136735e776f520b081cd374012852cb88cef9a88/library/Zend/Db/Statement.php#L140

9
ответ дан 8 December 2019 в 18:43
поделиться
Другие вопросы по тегам:

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