powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Вызов процедуры в IN()
6 сообщений из 6, страница 1 из 1
Вызов процедуры в IN()
    #33526807
g100m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
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.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
CREATE OR REPLACE FUNCTION get_node_childs(int4, int4, int4)
RETURNS TEXT AS '
DECLARE

	v_node_id ALIAS FOR $1;
	v_level_counter ALIAS FOR $2;
	v_auser_id ALIAS FOR $3;
	v_childs integer[] := \'{}\';

	node_rights int4;

BEGIN

	node_rights := get_rights_to_node(v_node_id, v_auser_id);

	IF node_rights & 1 THEN
		v_childs := get_node_childs_int(v_node_id, node_rights, v_level_counter, v_auser_id);
	END IF;

    RETURN array_to_string(v_childs, \',\');

END;
'
 LANGUAGE plpgsql
IMMUTABLE
RETURNS NULL ON NULL INPUT;


CREATE OR REPLACE FUNCTION get_node_childs_int(int4, int4, int4, int4)
RETURNS integer[] AS '
DECLARE

	v_node_id ALIAS FOR $1;
	v_parent_rights ALIAS FOR $2;
	v_level_counter ALIAS FOR $3;
	v_auser_id ALIAS FOR $4;

	v_childs integer[] := \'{}\';

	level_counter int4;

	vo_full_rights int4;
	parent_rights int4;
	node_info RECORD;

BEGIN

	level_counter := v_level_counter - 1;

	FOR node_info IN
		SELECT
			node.node_id,
			node.irf,
			node.owner,
			COALESCE(BIT_OR(acl.rights), 0) AS rights
		FROM node
		LEFT JOIN acl
			ON
				node.node_id = acl.node_id
			AND
				(
					acl.auser_id = v_auser_id
					OR
					acl.auser_id IN (SELECT parent_id FROM auser_to_auser WHERE auser_id = v_auser_id)
				)
		WHERE
			node.parent_id = v_node_id
		GROUP BY
			node.node_id,
			node.irf,
			node.owner
	LOOP

		IF node_info.irf <> 0 THEN
			parent_rights := v_parent_rights;
		ELSE
			parent_rights := 0;
		END IF;

		IF node_info.owner = v_auser_id OR v_auser_id = 3 THEN
			vo_full_rights := 63;
		ELSE
			vo_full_rights := (node_info.rights | (node_info.irf & parent_rights)) + 0;
		END IF;

		IF vo_full_rights <> 0 AND v_level_counter > 0 THEN
			v_childs := array_cat(v_childs, get_node_childs_int(node_info.node_id, vo_full_rights, level_counter, v_auser_id));
		END IF;

		IF vo_full_rights <> 0 THEN
			v_childs := array_append(v_childs, node_info.node_id);
		END IF;

    END LOOP;

    RETURN v_childs;

END;
'
 LANGUAGE plpgsql
IMMUTABLE
RETURNS NULL ON NULL INPUT;


При
Код: plaintext
SELECT * from get_node_childs( 117 ,  1 ,  3 );
как и положено возвращает строку id-шек, разделенных зяпятыми
При
Код: plaintext
1.
2.
SELECT * FROM node WHERE node_id IN(
	SELECT * from get_node_childs( 117 ,  1 ,  3 )
);
говорит
Код: plaintext
1.
2.
3.
4.
row number - 1  is out of range  0 ..- 1 
Total query runtime:  203  ms.
Data retrieval runtime:  47  ms.
 0  rows retrieved.

Не могу разобраться в чем причина такого поведения Э(
...
Рейтинг: 0 / 0
Вызов процедуры в IN()
    #33526846
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не путайте 2 разных! вещи
In(SELECT ...)
IN(1,2,3,...)

конструкция
In(SELECT ...) ищет совпадения с возвращаемым НАБОРОМ, а не строкой- списком.

ЧТобы вашу бодягу превратить в IN(1,2,3,...), надо сделать что-то наподобь:
Execute( 'SELECT * FROM t WHERE id IN(' || strValues ');'
...
Рейтинг: 0 / 0
Вызов процедуры в IN()
    #33526885
Opilki_Inside
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторSELECT * FROM node WHERE node_id IN(
SELECT * from get_node_childs(117, 1, 3)
);

попробуй

Код: plaintext
1.
SELECT * FROM node WHERE node_id IN(
SELECT get_node_childs( 117 ,  1 ,  3 ));
...
Рейтинг: 0 / 0
Вызов процедуры в IN()
    #33526932
g100m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
4321
ЧТобы вашу бодягу превратить в IN(1,2,3,...), надо сделать что-то наподобь:
Execute( 'SELECT * FROM t WHERE id IN(' || strValues ');'
В принципе да, как вариант сойдет, хотя и с довольно большим извратом )

Подобная строка формируется только для того, чтобы через pgmemcache запихать её в память на длительный срок (её формирование иногда довольно накладно)

Opilki_Inside
Попробуйте ...
Пустой результат с тем же сообщением (
...
Рейтинг: 0 / 0
Вызов процедуры в IN()
    #33528013
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
g100m Подобная строка формируется только для того, чтобы через pgmemcache запихать её в память на длительный срок (её формирование иногда довольно накладно)
а почему не попробовать вернуть из, скажем STAVLE ф-ии _набор_? Или проблема его закешировать?
...
Рейтинг: 0 / 0
Вызов процедуры в IN()
    #33529856
g100m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
4321 g100m Подобная строка формируется только для того, чтобы через pgmemcache запихать её в память на длительный срок (её формирование иногда довольно накладно)
а почему не попробовать вернуть из, скажем STAVLE ф-ии _набор_? Или проблема его закешировать?

Да, кэшируются только строки
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Вызов процедуры в IN()
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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