Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / RETURN NULL в функции, возвращающей множество / 10 сообщений из 10, страница 1 из 1
17.02.2016, 17:07
    #39173374
Valentine_vaia
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
Добрый день.
Приходится переводить древний проект с PostgreSQL версии 7.4 на версию 9.2
Большую часть явных ошибок уже исправлено.
Столкнулась с функциями, возвращающими множество (SETOF integer).
Раньше (в 7.4) в начале функции стояла проверка с возвращением NULL (компилятор пропускал ее, а сама функция и функция ее вызывающая корректно работали):

Код: plsql
1.
2.
3.
4.
5.
...
IF $2 IS NULL THEN
  RETURN NULL;
END IF;
...



Сейчас компилятор СУБД не воспринимает это для подобных функций. Рекомендует заменить на RETURN NEXT или RETURN QUERY.
Пробовала разные варианты, например RETURN NEXT NULL; RETURN;
Но логика работы с возвращаемым значением функции не отрабатывает. Подскажите как изменить условие, чтобы отработал ANY?
Результат возвращается и должен подставляться для проверки:
Код: plsql
1.
2.
3.
4.
...
IF $3=ANY(SELECT * FROM func($1,$2)) THEN 
  RETURN true;
END IF;
...
Рейтинг: 0 / 0
17.02.2016, 18:03
    #39173456
big-trot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
Valentine_vaia,

Код: sql
1.
func($1,$2)



что возвращает эта функция?
...
Рейтинг: 0 / 0
18.02.2016, 09:44
    #39173791
Valentine_vaia
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
big-trot,

набор чисел типа integer.
В функции находится по одному значению и возвращает через RETURN NEXT rec.ret;

В версии 7.4 при пустом параметре функция возвращала RETURN NULL;
Этот NULL попадал в выражение $3=ANY(SELECT * FROM func($1,$2), и оно оказывалось верным.
В версии 9.2 эти вещи так не работают.
...
Рейтинг: 0 / 0
18.02.2016, 10:47
    #39173847
big-trot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
Valentine_vaia,

может это как-то поможет

Код: sql
1.
2.
3.
4.
5.
IF (SELECT * FROM func($1,$2)) IS NULL THEN
  RETURN false;
ELSIF $3=ANY(SELECT * FROM func($1,$2)) THEN 
  RETURN true;
END IF;
...
Рейтинг: 0 / 0
18.02.2016, 11:42
    #39173930
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
Valentine_vaiabig-trot,

набор чисел типа integer.
В функции находится по одному значению и возвращает через RETURN NEXT rec.ret;

В версии 7.4 при пустом параметре функция возвращала RETURN NULL;
Этот NULL попадал в выражение $3=ANY(SELECT * FROM func($1,$2), и оно оказывалось верным.
В версии 9.2 эти вещи так не работают.

приведите для 7 возврат

Код: sql
1.
2.
3.
4.
5.
6.
SELECT
	1 =ANY(VALUES (NULL),(4),(2))
	,1 =ANY(VALUES (NULL),(1),(2))
	,1 =ANY(VALUES (4),(2))
-------------------
;t;f


смутно помнится что где то что то менялось на сравнения с NULL--содержащими.
но кажется для компаундов, а не для array-ев.
...
Рейтинг: 0 / 0
18.02.2016, 16:08
    #39174457
Valentine_vaia
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
qwwq,

Выполнила ваш пример под версией 7.4

Код: sql
1.
2.
3.
4.
5.
SELECT 1=ANY(array[NULL,4,2])
			,1=ANY(array[NULL,1,2])
			,1=ANY(array[4,2])
-----------------------
;;f



Мне теперь ясно в чем проблема. Если будут предложения, как поправить это - пишите.

Благодарю за помощь.
...
Рейтинг: 0 / 0
18.02.2016, 16:56
    #39174527
Valentine_vaia
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
qwwq,

Возвращает true, если в наборе нет NULL.

Код: sql
1.
2.
3.
4.
5.
6.
SELECT 1=ANY(array[NULL,4,2])
			,1=ANY(array[NULL,1,2])
			,1=ANY(array[4,2])
			,1=ANY(array[1,2])
-----------------------
;;f;t
...
Рейтинг: 0 / 0
18.02.2016, 18:22
    #39174632
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
Valentine_vaia,

всего богатства сочетаний отсюда не видно.

попробую выдать завиральную идею, что return NULL; (без next) в STF в 7.x могло быть просто эквивалентно RETURN; с пустым сетом в выводе.

вы покажите вывод f при $2 == NULL
Код: sql
1.
SELECT * FROM func('что--то',NULL) 


-- будет легче понять, куда копать.
...
Рейтинг: 0 / 0
19.02.2016, 12:46
    #39175175
Valentine_vaia
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
qwwq,

Версия 7.4

с нулевым параметром

Код: sql
1.
2.
3.
SELECT * FROM func('cls', NULL)
-----------
NULL



с параметрами

Код: sql
1.
2.
3.
SELECT * FROM func('cls', 1657)
-----------
4729;1656;1641



Версия 9.2 (без изменений)

с любым параметром

Код: 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.
SELECT * FROM func('cls', NULL)
-----------

[Err] ОШИБКА:  в функции, возвращающей множество, RETURN должен быть без параметров
LINE 6:  IF $2 IS NULL THEN  RETURN NULL;  END IF;
                                    ^
HINT:  Используйте RETURN NEXT или RETURN QUERY.
QUERY:  
DECLARE
 cmnd text;
 rec RECORD;
BEGIN
 IF $2 IS NULL THEN  RETURN NULL;  END IF;
 IF $1 IS NULL THEN
  ...
 ELSE
  ...
 END IF;
 IF rec.ret IS NOT NULL THEN
  FOR i IN array_lower(rec.ret,1) .. array_upper(rec.ret,1) LOOP
   RETURN NEXT rec.ret[i];
  END LOOP; 
 END IF;
 RETURN;
END;

CONTEXT:  компиляция функции PL/pgSQL "func" в районе строки 6



Версия 9.2

Изменила возврат RETURN NULL; на обычный RETURN; все заработало корректно
Я правлю сразу несколько ошибок, могла затронуть цепочку.

Код: sql
1.
2.
3.
SELECT * FROM func('cls', NULL)
-----------
NULL



Код: sql
1.
2.
3.
SELECT * FROM func('cls', 1657)
-----------
4729,1656,1641



+++++++++++++++++++++++++++++++++++++++++++++
Версия 9.2
Изменила возврат RETURN NULL; на обычный RETURN NEXT NULL; RETURN; все заработало корректно
Я правлю сразу несколько ошибок, могла затронуть цепочку.

Код: sql
1.
2.
3.
SELECT * FROM func('cls', NULL)
-----------
NULL


Код: sql
1.
2.
3.
SELECT * FROM func('cls', 1657)
-----------
4729,1656,1641
...
Рейтинг: 0 / 0
19.02.2016, 12:55
    #39175194
Valentine_vaia
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RETURN NULL в функции, возвращающей множество
Спасибо за помощь, нашла способ отлаживать выполнение скриптов и данных к ним.

В данной ситуации, как и советует компилятор

для функций, возвращающих множество (например, SETOF integer)
в версии 7.4 использовалось RETURN NULL;
в версии 9.2 можно заменить на RETURN; или RETURN NULL; RETURN;


Я дальше буду переводить проект. Такая ситуация встречается еще в нескольких местах. И конечно нужно рассматривать данные, которые передаются таким функциям. Ибо как показала практика, если в массиве есть NULL и искомое значение, то не сможеет найти искомое значение. (см. 18834068 и 18836427 )
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / RETURN NULL в функции, возвращающей множество / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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