Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Перебор массива в PL/pgSQL / 9 сообщений из 9, страница 1 из 1
22.08.2008, 10:44
    #35500966
webus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перебор массива в PL/pgSQL
Доброй всем пятницы! Есть вопрос. Передаем в функцию параметр типа
Код: plaintext
myval BIGINT[]
Требуется в хранимой процедуры последовательно перебрать все элементы массива и выполнить над каждым операцию.
Если мыслить на ООП то что то типа этого:
Код: plaintext
foreach(string s in mystr) { делаем что-то с переменной s }
как это можно сделать на PL/pgSQL ?
...
Рейтинг: 0 / 0
22.08.2008, 11:07
    #35501046
Konstantin~
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перебор массива в PL/pgSQL
пример для двухмерного массива, естествнно все тоже самое и для одномерного массива, только
циферку убрать из функций котореы определяют границы массива, t.e. array_upper(my_array)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
...
DEFINE
   -- define 2-dim array  
   my_array INTEGER[] := '{{1,10},{2,20}}';
BEGIN
   FOR i IN COALESCE(array_lower(my_array, 1 ), 0 ) .. COALESCE(array_upper(my_array, 1 ),- 1 ) LOOP
		RAISE NOTICE 'array[i][1]=%', my_array[i][ 1 ];  
                RAISE NOTICE 'array[i][2]=%', my_array[i][ 2 ]; 
                --
                --  do something with values
                --
   END LOOP;
...
END
...
Рейтинг: 0 / 0
22.08.2008, 12:19
    #35501292
webus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перебор массива в PL/pgSQL
Код: 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.
CREATE OR REPLACE FUNCTION ORDERS_APPEND(
	NUM BIGINT,
	STATE T_ORDER_STATE,
	DATEREG TIMESTAMP,
	BEGINDATE TIMESTAMP,
	DATEOFPERF TIMESTAMP,
	EXECUTORS BIGINT[],
	RESPONSIBLES BIGINT[],
	CONCORDANCES BIGINT[],
	PATH_TO_FILE VARCHAR( 255 ),
	ORDNAME VARCHAR( 100 ),
	SUMMARY VARCHAR( 1000 ),
	PUBLISHER BIGINT) RETURNS INTEGER AS $$
DECLARE
	--
	FILE_UID BIGINT;
	ORDER_UID BIGINT;
BEGIN
	--LOAD FILE TO DB
	INSERT INTO FILE_STORAGE(FS) VALUES(lo_import(FILE_UID)) RETURNING uid INTO FILE_UID;
	INSERT INTO ORDERS(
		ORD_NUM,ORD_STATE,ORD_DATEREG,ORD_BEGINDATE,ORD_DATEOFPERF,ORD_FILE_UID,
		ORD_NAME,ORD_SUMMARY,ORD_PUBLISHER)
		VALUES(
			NUM,
			STATE,
			DATEREG,
			BEGINDATE,
			DATEOFPERF,
			FILE_UID,
			ORDNAME,
			SUMMARY,
			PUBLISHER) RETURNING uid INTO ORDER_UID;
	FOR i IN COALESCE(array_lower(EXECUTORS), 0 ) .. COALESCE(array_upper(EXECUTORS),- 1 ) LOOP
		INSERT INTO ORD2EXECUTOR(ORD_UID,USR_UID) VALUES(ORDER_UID,EXECUTORS[i]);
	END LOOP;
	FOR i IN COALESCE(array_lower(RESPONSIBLES), 0 ) .. COALESCE(array_upper(RESPONSIBLES),- 1 ) LOOP
		INSERT INTO ORD2RESPONSIBLE(ORD_UID,USR_UID) VALUES(ORDER_UID,RESPONSIBLES[i]);
	END LOOP;
	FOR i IN COALESCE(array_lower(CONCORDANCES), 0 ) .. COALESCE(array_upper(CONCORDANCES),- 1 ) LOOP
		INSERT INTO ORD2CONCORDANCE(ORD_UID,USR_UID) VALUES(ORDER_UID,CONCORDANCES[i]);
	END LOOP;
	RETURN  1 ;
END;
$$ LANGUAGE plpgsql;
	

скажите что не так в функции

вызываю ее так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT ORDERS_APPEND(
	 1 ,
	'создан',
	current_timestamp,
	current_timestamp,
	current_timestamp,
	'{1,2}',
	'{1}',
	'{1,2}',
	'SYS.7Z',
	'TEST',
	'TEST SUMMARY',
	 1 );

пишет ошибку:
ERROR: function orders_append(integer, t_order_state, timestamp with time zone, timestamp with time zone, timestamp with time zone, bigint[], bigint[], bigint[], unknown, unknown, unknown, integer) does not exist
LINE 3: SELECT ORDERS_APPEND(
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
...
Рейтинг: 0 / 0
22.08.2008, 12:44
    #35501381
webus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перебор массива в PL/pgSQL
Исправил так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT ORDERS_APPEND(
	 1 ,
	CAST('создан' AS T_ORDER_STATE),
	current_timestamp,
	current_timestamp,
	current_timestamp,
	ARRAY[ 1 , 2 ],
	ARRAY[ 1 ],
	ARRAY[ 1 , 2 ],
	CAST('SYS.7Z' AS VARCHAR( 255 )),
	CAST('TEST' AS VARCHAR( 100 )),
	CAST('TEST SUMMARY' AS VARCHAR( 1000 )),
	 1 );

Та же ошибка тоже не хочет.
...
Рейтинг: 0 / 0
22.08.2008, 12:56
    #35501417
webus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перебор массива в PL/pgSQL
webusИсправил так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT ORDERS_APPEND(
	 1 ,
	CAST('создан' AS T_ORDER_STATE),
	current_timestamp,
	current_timestamp,
	current_timestamp,
	ARRAY[ 1 , 2 ],
	ARRAY[ 1 ],
	ARRAY[ 1 , 2 ],
	CAST('SYS.7Z' AS VARCHAR( 255 )),
	CAST('TEST' AS VARCHAR( 100 )),
	CAST('TEST SUMMARY' AS VARCHAR( 1000 )),
	 1 );

Та же ошибка тоже не хочет.

не воспринимает он current_timestamp. понял. буду разбираться
...
Рейтинг: 0 / 0
22.08.2008, 13:41
    #35501556
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перебор массива в PL/pgSQL
webusне воспринимает он current_timestamp. понял. буду разбиратьсяфункция определена над "DATEREG TIMESTAMP" - без time zone, а current_timestamp возвращает тип timestamp with time zone. то есть или изменить на а) "DATEREG TIMESTAMP WITH TIME ZONE", или б) current_timestamp()::timestamp.
...
Рейтинг: 0 / 0
22.08.2008, 14:05
    #35501663
webus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перебор массива в PL/pgSQL
LeXa NalBat webusне воспринимает он current_timestamp. понял. буду разбиратьсяфункция определена над "DATEREG TIMESTAMP" - без time zone, а current_timestamp возвращает тип timestamp with time zone. то есть или изменить на а) "DATEREG TIMESTAMP WITH TIME ZONE", или б) current_timestamp()::timestamp.

использовать стал localtimestamp

все проходит. только теперь ругается что нет функции lo_import (
...
Рейтинг: 0 / 0
22.08.2008, 15:01
    #35501880
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перебор массива в PL/pgSQL
webusвсе проходит. только теперь ругается что нет функции lo_import (может быть опять ошибка в несоответствии типов?

Код: plaintext
1.
2.
3.
DECLARE
	FILE_UID BIGINT;
...
... lo_import(FILE_UID) ...

Код: plaintext
1.
2.
3.
                        List of functions
   Schema   |   Name    | Result data type | Argument data types
------------+-----------+------------------+---------------------
 pg_catalog | lo_import | oid              | text
...
Рейтинг: 0 / 0
22.08.2008, 15:08
    #35501903
webus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перебор массива в PL/pgSQL
LeXa NalBat webusвсе проходит. только теперь ругается что нет функции lo_import (может быть опять ошибка в несоответствии типов?

Код: plaintext
1.
2.
3.
DECLARE
	FILE_UID BIGINT;
...
... lo_import(FILE_UID) ...

Код: plaintext
1.
2.
3.
                        List of functions
   Schema   |   Name    | Result data type | Argument data types
------------+-----------+------------------+---------------------
 pg_catalog | lo_import | oid              | text


Да верно! Спасибо!
А обязательно ли пользователя делать супер юзеров для работы с BLOB ?

ERROR: must be superuser to use server-side lo_import()
HINT: Anyone can use the client-side lo_import() provided by libpq.
CONTEXT: SQL statement "INSERT INTO FILE_STORAGE(FS) VALUES(lo_import( $1 )) RETURNING uid"
PL/pgSQL function "orders_append" line 7 at SQL statement
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Перебор массива в PL/pgSQL / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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