Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Пятничная задача (регулярные выражения)  [new]
Tolmachov Dmitiry
Member

Откуда: Москва, Пенза
Сообщений: 1520
Тут недавно проскакивала тема - требовалось распарсить строку с SELECT-ом, а именно получить список таблиц, участвующих в запросе. Я решил помочь и написать конструкцию, которая бы вырезала из строки список таблиц. Для начала задачка казалась простой. Примем, что список требуется "как есть", то есть через запятую, с алиасами. Примем так же, что запрос простой - без вложенных запросов и наворотов. Используем Oracle 10g и функции regexp_xxxxxx. Но в результате получить одноходовое решение так и не получилось. Трудность заключается в том, что наличие (или отсутствие) секции where/order by/group by в строке не дает использовать универсальный шаблон. Или мне просто не удалось такой шаблон создать. Может кому-нибудь удасться создать универсальный шаблон?
12 май 06, 11:36    [2656350]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116299
Мне кажется, здесь хорошо получается REGEXP_REPLACE

select regexp_replace(regexp_replace(lower('SELECT sysdate from dual order by 1)','.+from'),
'(where|group|order).+') from dual
12 май 06, 12:32    [2656685]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
Tolmachov Dmitiry
Member

Откуда: Москва, Пенза
Сообщений: 1520
Хм, у меня сия конструкция не работает
Oracle Database 10g Enterprise Edition Release 10.1.0.4.0 - Prod
PL/SQL Release 10.1.0.4.0 - Production
CORE	10.1.0.4.0	Production
Кстати, от LOWER можно избавиться, введя match_parameter = 'i'
12 май 06, 12:37    [2656703]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116299
Tolmachov Dmitiry
Хм, у меня сия конструкция не работает
Oracle Database 10g Enterprise Edition Release 10.1.0.4.0 - Prod
PL/SQL Release 10.1.0.4.0 - Production
CORE	10.1.0.4.0	Production
Кстати, от LOWER можно избавиться, введя match_parameter = 'i'


10.2.0.1 - все в порядке.
Про i я конечно забыл, только привыкаю к регулярным выражениям...
12 май 06, 12:39    [2656710]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
Выкусывать FROM это хорошо, но как быть с синтаксисом соединения ANSI SQL?
12 май 06, 12:42    [2656730]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
Tolmachov Dmitiry
Member

Откуда: Москва, Пенза
Сообщений: 1520
Что-то у тебя со скобками там не то. Вот восстановленный вариант
select regexp_replace(regexp_replace('SELECT * from table1 t1, table2 t2 where t1.pkey = t2.pkey order by 1', '.+ from', '', 1, 1, 'i'),
 '(where|group|order).+', '', 1, 1, 'i')
 from dual
Заработало!
12 май 06, 12:44    [2656738]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116299
mcureenab
Выкусывать FROM это хорошо, но как быть с синтаксисом соединения ANSI SQL?


Tolmachov Dmitry
Примем, что список требуется "как есть", то есть через запятую, с алиасами. Примем так же, что запрос простой - без вложенных запросов и наворотов


Приняли
12 май 06, 12:45    [2656751]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116299
Tolmachov Dmitiry
Что-то у тебя со скобками там не то. Вот восстановленный вариант
select regexp_replace(regexp_replace('SELECT * from table1 t1, table2 t2 where t1.pkey = t2.pkey order by 1', '.+ from', '', 1, 1, 'i'),
 '(where|group|order).+', '', 1, 1, 'i')
 from dual
Заработало!


Это я в последний момент дописывал lower :(
Так у Вас в версии тоже работает ?
12 май 06, 12:49    [2656782]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
Tolmachov Dmitiry
Member

Откуда: Москва, Пенза
Сообщений: 1520
Да. Дело было всего лишь в скобках
12 май 06, 12:50    [2656791]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
dmidek

select regexp_replace(regexp_replace(lower('SELECT sysdate from dual order by 1)'),'.+from'),
'(where|group|order).+') from dual

:)
12 май 06, 12:58    [2656841]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
Ещё бяка. А что, если в секции from фигурирует подзапрос?
12 май 06, 13:01    [2656862]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
create table my_group as select * from dual;
select regexp_replace(regexp_replace(lower('SELECT sysdate from my_group order by 1)'),'.+from'),
'(where|group|order).+') from dual;

 my_
тщательнЕе бы (имхо :)
12 май 06, 13:02    [2656867]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
Tolmachov Dmitiry
Member

Откуда: Москва, Пенза
Сообщений: 1520
mcureenab
Ещё бяка. А что, если в секции from фигурирует подзапрос?
Вот, переходим к сложным запросам
12 май 06, 13:03    [2656877]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
Timm
Member

Откуда: Moscow, Ё-burg
Сообщений: 3696
Tolmachov Dmitiry
mcureenab
Ещё бяка. А что, если в секции from фигурирует подзапрос?
Вот, переходим к сложным запросам

+ иногда нужно указывать пробелы/скобки до/после from, where, ...
12 май 06, 13:06    [2656901]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116299
orawish
create table my_group as select * from dual;
select regexp_replace(regexp_replace(lower('SELECT sysdate from my_group order by 1)'),'.+from'),
'(where|group|order).+') from dual;

 my_
тщательнЕе бы (имхо :)


Да, я про такое думал, но ведь изначальные допущения все равно делают задачу совсем нестрогой. ИМХО вложенный запрос будет с гораздо большей вероятностью, чем my_group.
А по сути замечания это вроде лечится

'( where | group | order ).+'
12 май 06, 13:08    [2656908]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
dmidek
А по сути замечания это вроде лечится

'( where | group | order ).+'


Лечиться но не так. Пример:

select * from dual "d"where'X'=dummy;

D
-
X
12 май 06, 13:15    [2656946]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
dmidek
orawish
create table my_group as select * from dual;
select regexp_replace(regexp_replace(lower('SELECT sysdate from my_group order by 1)'),'.+from'),
'(where|group|order).+') from dual;

 my_
тщательнЕе бы (имхо :)


Да, я про такое думал, но ведь изначальные допущения все равно делают задачу совсем нестрогой. ИМХО вложенный запрос будет с гораздо большей вероятностью, чем my_group.
А по сути замечания это вроде лечится

'( where | group | order ).+'

Конечно, лечится.. Но тут вариации начинаются на тему конца строки,тамбуленциев,кавычков/апострофов(и что там в них:) и т.д и т.п.
12 май 06, 13:16    [2656951]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116299
2 orawish и mcureenab.
Ребята, повторюсь, я абсолютно согласен с Вашими замечаниями.
Я в регулярных выражениях новичок и был очень доволен, что даже такую ограниченную задачу удалось решить. Если Вы покажете, как подкрутить так, чтобы сделать решение этой задачи более универсальным, было бы очень интересно. Не рассматривайте плиз как ответный подкол ...
12 май 06, 14:13    [2657334]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
dmidek
Если Вы покажете, как подкрутить так, чтобы сделать решение этой задачи более универсальным, было бы очень интересно.


Это задача лексического анализа. Лексические правила обычно формулируются на языке регулярных выражений (возможно в этом и кроется подвох), но функция REGEXP_REPLACE не является лексическим анализатором.
12 май 06, 15:22    [2657869]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
mcureenab
dmidek
Если Вы покажете, как подкрутить так, чтобы сделать решение этой задачи более универсальным, было бы очень интересно.


Это задача лексического анализа. Лексические правила обычно формулируются на языке регулярных выражений (возможно в этом и кроется подвох), но функция REGEXP_REPLACE не является лексическим анализатором.

+1
Ну и весьма сомневаюсь в практичности потуг засунуть в один запрос (с любой вложенностью любых регулярных и прочих функций/операторов)
Тут ить одна длина операндов наводит грусть.
А для обучалова/развлекалова - ну, нормально..
12 май 06, 15:51    [2658101]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116299
orawish
А для обучалова/развлекалова - ну, нормально..

А, ну тогда хорошо
12 май 06, 15:52    [2658108]     Ответить | Цитировать Сообщить модератору
 Re: Пятничная задача (регулярные выражения)  [new]
Владимир Бегун
Member

Откуда: Redwood Shores, CA USA
Сообщений: 1707
CREATE GLOBAL TEMPORARY TABLE "FROM"
(
  statement_id       varchar2(30),
  plan_id            number,
  timestamp          date,
  remarks            varchar2(4000),
  operation          varchar2(30),
  options            varchar2(255),
  object_node        varchar2(128),
  object_owner       varchar2(30),
  object_name        varchar2(30),
  object_alias       varchar2(65),
  object_instance    numeric,
  object_type        varchar2(30),
  optimizer          varchar2(255),
  search_columns     number,
  id                 numeric,
  parent_id          numeric,
  depth              numeric,
  position           numeric,
  cost               numeric,
  cardinality        numeric,
  bytes              numeric,
  other_tag          varchar2(255),
  partition_start    varchar2(255),
  partition_stop     varchar2(255),
  partition_id       numeric,
  other              long,
  distribution       varchar2(30),
  cpu_cost           numeric,
  io_cost            numeric,
  temp_space         numeric,
  access_predicates  varchar2(4000),
  filter_predicates  varchar2(4000),
  projection         varchar2(4000),
  time               numeric,
  qblock_name        varchar2(30),
  other_xml          clob
);
EXPLAIN PLAN INTO "FROM" FOR
WITH a AS (
  SELECT "FROM".statement_id
    FROM "FROM" "FROM"
           , "FROM" "FROM "
) SELECT *
    FROM a
   GROUP BY statement_id
  HAVING COUNT(*) <> (
                  SELECT COUNT(*)
                    FROM user_objects
);
SELECT [DISTINCT] object_name FROM "FROM" ...
-- 
Vladimir Begun | http://alexeymazanov.narod.ru/
The statements and opinions expressed here are my own
and do not necessarily represent those of Oracle.
12 май 06, 19:58    [2659267]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить