powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Common Procedure Expressions
17 сообщений из 17, страница 1 из 1
Common Procedure Expressions
    #39330585
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EXECUTE STATEMENT (:varchar_variable) - сколько раз препарируется? При каждом исполнении или только при первом ?

Что-то мне захотелось Common Procedure Expressions :-)
Или Generic SQL Programming :-)
Или u name it

Простой пример: есть несколько древовидных справочников.
Типа "лист ссылается на свою ветку-владельца" через FK->PK.
Унаследованных. То есть столбцы называются как хотят.
Хотя бы типы, кажется, везде integer. Но в идеале от них бы отвязаться бы тоже...

Хочется делать join'ы других таблиц с несколькими выбираемыми пользователем "подкустами" справочников

Можно выбирать ID через With Recursive но это как-то не очень красиво.
Лучше подходят, кажется, вложенные диапазоны.

И для любой таблицы в отдельности это просто

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
ALTER TABLE T1
  ADD L Integer;
  
ALTER TABLE T1
  ADD R Integer;  
  
CREATE UNIQUE INDEX T1_L ON T1 (L);
CREATE UNIQUE INDEX T1_R ON T1 (R);


CREATE OR ALTER TRIGGER T1_Tree_Changed FOR T1
ACTIVE AFTER INSERT OR UPDATE 
AS
begin
  if ((NEW.id <> OLD.id) or (NEW.parent is distinct from OLD.Parent)) then
    if ((old.l is not null) or (old.r is not null)) then
    begin
      update T1 set l = null, r = null;
      -- new.l = null;  needed for before-xxx triggers
      -- new.r = null;
    end
end  



CREATE OR ALTER TRIGGER T1_PK FOR T1
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  if (new.ID IS NULL) then
      SELECT NEXT VALUE FOR T1_GEN from rdb$database into new.ID;
end



create or alter procedure UPD_T1_LR_1 (
    R_IN integer = null,
    ITEM_ID integer = null)
returns (
    R_OUT integer)
as
declare variable L_VAR integer;
declare variable LOOP_ID integer;
begin
 R_OUT = 0;
 if (exists( select * from t1 where id = :item_id )) then begin
   L_Var = coalesce(:R_IN, 0) + 1;
   R_OUT = :L_Var;
 end

 for select id from t1
     where parent is not distinct from :item_id
     order by id  -- ordering is not supported in With Recursive
     into loop_id
 do
 begin
   execute procedure UPD_t1_LR_1 (:R_OUT, :loop_id)
                returning_values (:R_OUT);
 end

 R_OUT = :R_OUT + 1;
 update t1 set
   L = :l_var, 
   R = :r_out
 where id = :item_id;
end^



Вторая процедура.... писать её для каждого справочника не хочется.
В конце концов она одна и та же, с точностью до - table name, id column name and type, parent id column name, left-bound and right-bound column names

т.е. можно добавить в неё еще один входящий параметр - текст её тела в виде строки - и пусть она сама себе вызывает рекурсивно через Execute Statement....

но как-то это очень хитровыподвернуто

И вот тут бы какое-нибудь временно-объявленное тело по аналогии с CTE бы хорошо подошло

with statement ..... as TempRecursiveSP do begin
execute procedure TempRecursiveSP
end;

или

with block ..... as TempRecursiveSP do begin
execute procedure TempRecursiveSP
end;
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330611
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
исходный пост и первый комментарий - 19804570
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330614
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в oracle 12 есть with function выглядит это примерно так:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
WITH
FUNCTION get_domain(url VARCHAR2) RETURN VARCHAR2 IS
   pos BINARY_INTEGER;
   len BINARY_INTEGER;
BEGIN
   pos := INSTR(url, 'www.');
   len := INSTR(SUBSTR(url, pos + 4), '.') - 1;
   RETURN SUBSTR(url, pos + 4, len);
END;
SELECT DISTINCT get_domain(catalog_url)
FROM product_information;



мы бы тоже моли расширить наш DSQL так чтобы можно было писать WITH {PROCEDURE | FUNCTION}

Если есть желание делай тикет в трекере на новую фичу

З.Ы. Насчёт WITH STATMENT в топку
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330621
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисЕсли есть желание делай тикет в трекере на новую фичу

Желание-то есть, только сначала обсудить надо, как его делать ,как его не делать, чтобы в трекер было что писать кроме ссылки на форум

Симонов ДенисЕсли есть желание делай тикет в трекере на новую фичу

Желание-то есть, только сначала обсудить надо, как его делать ,как его не делать, чтобы в трекер было что писать кроме ссылки на форум[/quote]
[quote Arioch]Симонов Денисwith function выглядит это примерно так:

в этом пpимере функций то ли не может в рекурсию, то ли не показано


Симонов ДенисWITH STATMENT в топку

не принципиально

with block или with function вполне может состоять из execute statement

тут фишка в создании тела процедуры на лету, то есть в качестве параметров чтобы передавалась таблица и столбцы

и тут либо вводить в PSQL типы "столбец" и "таблица", либо таки создавтаь тело как VARCHAR
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330627
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну либо делать, чтобы EXECUTE STATEMENT препарировался только при первом вызове, а не при повторных

но с точки зрения реализации.... делать "унутре неонку", чтобы к каждому varchar переменному подвязывать BLR-кэш.... Бррр....
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330675
afgm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochну либо делать, чтобы EXECUTE STATEMENT препарировался только при первом вызове, а не при повторных
А разве не так происходит? Трейс говорит что один раз препарится.

По теме, вместо with function приходится делать execute block с suspend-ом и локальной функцией. Отсутствие lateral обходится аналогичным способом.
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330690
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
afgm,

есть надежда на то что lateral появится в Firebird 4.0 CORE-3435
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330695
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
afgmОтсутствие lateral

?

afgmА разве не так происходит? Трейс говорит что один раз препарится.

Там может быть кэш запросов.... а может не быть, хз... Implementation detail, на которую не хочется завязываться. И которую пока никто из гуру не подтвердил.

Плюс к тому надо придумать, что делать с рекурсивностью в данном случае. Может быть и ничего, кэшу пофигу пока текст запроса не менялся. А м.б. и нет....
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330697
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Дениснадежда на то что lateral появится в Firebird 4.0 CORE-3435

ага, кажется понял, внесение контекста внутрь derived
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330723
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochТам может быть кэш запросов.... а может не быть, хз...Небольшой кеш есть
AriochImplementation detail, на которую не хочется завязываться.И правильно
AriochИ которую пока никто из гуру не подтвердилПотому что AriochImplementation detail, на которую не хочется завязываться
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39330736
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,

ну вот это же тоже ответ, что "препарируется столько раз, сколько повезёт" :-)

а чтобы не завязыватсья - надо эту практику лeгализовать

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

с моей стороны хотелки :
1) рекурсия такого блока, желательно прямая, хотя в крайнем случае и через прокладку из вторичной функции сойдет
2) возможность передать в параметры relation и column напрямую, а не как строковой литерал для сборки execute statement
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39332798
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
товарищи гуру, господа птицеводы...

какие-то осмысленные замечания будут?

а то ж я дуриком-то тикет составлю и будем там как дураки по-английски обсуждать, когда можно бы было по-русски
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39332807
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

я свои уже высказал. Мне кажется надо делать похоже на Oracle (WITH PROCEDURE, WITH FUNCTION). Только фичу с WITH STATEMENT в топку.
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39332843
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochкакие-то осмысленные замечания будут?А где осмысленное и конкретное предложение ? Без воды и философии
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39332866
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,

в таком виде пойдёт?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
WITH {<function> | <procedure> | <cte>} [, {<function> | <procedure> | <cte>} ...]
<select statement>

<function> ::= 
  FUNCTION func_name [(<in_impl_params>)]
  RETURNS <type> [COLLATE collation] [DETERMINISTIC]
  AS
    <declarations>
  BEGIN
    <PSQL_statements>]
  END

<procedure> ::= 
  PROCEDURE proc_name [(<in_impl_params>)]
  RETURNS (<out_params>)
  AS
    <declarations>
  BEGIN
    <PSQL_statements>]
  END

пример использования

Код: plsql
1.
2.
3.
4.
5.
6.
7.
WITH 
  FUNCTION sum_args(a int, b int) RETURN int
  AS
  BEGIN
    RETURN a+b;
  END
SELECT sum_args(1, 2) FROM RDB$DATABASE
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39332873
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

пойдёт. Только не понятно кто и когда этим сможет заняться
...
Рейтинг: 0 / 0
Common Procedure Expressions
    #39332876
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,

ну, это же просто предложение. Когда-нибудь в будущем.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Common Procedure Expressions
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]