Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Почему функция вызывается 2 раза? / 25 сообщений из 38, страница 1 из 2
14.04.2017, 16:18
    #39438850
Gogol
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
Добрый день.
Проясните механизм обращения к функции:

Код: plsql
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.
// Создадим сиквенс для подсчета обращений.
CREATE  SEQUENCE sq_ttt;

// Создадим тип
CREATE TYPE TYPE_DATA_QNT AS OBJECT (
         oper_date date,
         qnt0  number,
         qnt1  number,
         qnt2  number
);
/


// Создадим функцию возвращающую объект созданного типа.
CREATE or replace 
function test_TYPE_DATA_QNT RETURN TYPE_DATA_QNT
IS
  v_sq integer;
BEGIN
  v_sq :=  sq_ttt.nextval;
  RETURN  TYPE_DATA_QNT(sysdate,0,0,0);
END;
/

// Дернем значения сиквенса
// Следующий
SELECT sq_ttt.nextval FROM dual;


Nextval
1

Код: plsql
1.
2.
// Текущий
SELECT sq_ttt.currval FROM dual;



currval
1

Код: plsql
1.
2.
3.
4.
// Вызываем функцию 2 раза, проверяем по значению сиквенса
SELECT value(test_TYPE_DATA_QNT).oper_date, value(test_TYPE_DATA_QNT).qnt0 FROM dual;

SELECT sq_ttt.currval FROM dual;


currval
3

Код: plsql
1.
2.
3.
4.
5.
6.
// Вызваем функцию во вложенном запросе - один раз.
SELECT 
      value(test_TYPE_DATA_QNT) as dat 
FROM dual;

SELECT sq_ttt.currval FROM dual;


currval
4

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
// Вроде то же самое, но функция вызывается дважды, почему?
SELECT v.dat.oper_date, v.dat.qnt0
FROM
(
    SELECT 
      value(test_TYPE_DATA_QNT) as dat 
    FROM dual
) v    

SELECT sq_ttt.currval FROM dual;


currval
6

Почему в последнем запросе функция вызывается дважды, а не один раз?
...
Рейтинг: 0 / 0
14.04.2017, 16:24
    #39438855
XMLer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
Gogol,
По разу на каждый зависимый от функции элемент select кляузы. Хочешь вызвать один раз- так и скажи. Ты же оставил это на откуп оптимизатору.
...
Рейтинг: 0 / 0
14.04.2017, 16:27
    #39438859
Gogol
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
XMLer,

Как вызвать один раз?
...
Рейтинг: 0 / 0
14.04.2017, 16:28
    #39438860
JaRo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
/*+NO_MERGE*/ во внутренний запрос и будет как ждёте
...
Рейтинг: 0 / 0
14.04.2017, 16:45
    #39438865
Gogol
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
JaRo,

Да, ваша правда

Код: plsql
1.
SELECT pc.sq_ttt.currval FROM dual;



CURRVAL
18

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT v.dat.oper_date, v.dat.qnt0
FROM
(
    SELECT /*+NO_MERGE */
      value(pc.test_TYPE_DATA_QNT) as dat 
    FROM dual
) v;    

SELECT pc.sq_ttt.currval FROM dual;



CURRVAL
19

Спасибо, читаю про данный хинт.
...
Рейтинг: 0 / 0
14.04.2017, 16:53
    #39438873
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
JaRo/*+NO_MERGE*/ во внутренний запрос и будет как ждёте

Будет ли?

Код: plsql
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.
SQL> SELECT sq_ttt.currval FROM dual;

   CURRVAL
----------
         3

SQL> SELECT v.dat.oper_date, v.dat.qnt0
  2  FROM
  3  (
  4      SELECT /*+ NO_MERGE */
  5        value(test_TYPE_DATA_QNT) as dat 
  6      FROM dual
  7  ) v    
  8  /

DAT.OPER_   DAT.QNT0
--------- ----------
14-APR-17          0

SQL> SELECT sq_ttt.currval FROM dual;

   CURRVAL
----------
         5

SQL>



А вот так будет:

Код: plsql
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.
SQL> create or replace
  2    type TYPE_DATA_QNT_TBL
  3      as table of TYPE_DATA_QNT
  4  /

Type created.

SQL> select  oper_date,
  2          qnt0
  3    from  table(
  4                TYPE_DATA_QNT_TBL(
  5                                  test_TYPE_DATA_QNT
  6                                 )
  7               )
  8  /

OPER_DATE       QNT0
--------- ----------
14-APR-17          0

SQL> SELECT sq_ttt.currval FROM dual;

   CURRVAL
----------
         6

SQL> 



SY.
...
Рейтинг: 0 / 0
14.04.2017, 16:57
    #39438877
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
GogolСпасибо, читаю про данный хинт.

Читай, может вычитаешь что hint это подсказка а не требование так-что оптимайзер может по...ить твой хинт.

SY.
...
Рейтинг: 0 / 0
14.04.2017, 17:01
    #39438881
Gogol
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
SY,

Да, интересное поведение.
Сможете написать с чем связано такое поведение хинта на разных инстансах?
...
Рейтинг: 0 / 0
14.04.2017, 17:04
    #39438883
Gogol
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
Всего то хотел пару значений из функции передать не прибегая к конвеерной(pipelined) функции.
...
Рейтинг: 0 / 0
14.04.2017, 17:05
    #39438885
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
...
Рейтинг: 0 / 0
14.04.2017, 17:09
    #39438886
Vint
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
Gogol,
вот поэтому изначальную задачу надо формулировать. и потом пути решения уже описывай. открой для себя in out параметры в функциях.
...
Рейтинг: 0 / 0
14.04.2017, 19:21
    #39438951
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
VintGogol,
вот поэтому изначальную задачу надо формулировать. и потом пути решения уже описывай. открой для себя in out параметры в функциях.

Ну тут ты сVintил - нельзя функцию с OUT, IN/OUT параметрами вызвать из SQL.

SY.
...
Рейтинг: 0 / 0
15.04.2017, 07:02
    #39439035
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
SYНу тут ты сVintил - нельзя функцию с OUT, IN/OUT параметрами вызвать из SQL.А я в 12с могу. Хоть процедуру.
...
Рейтинг: 0 / 0
15.04.2017, 13:29
    #39439110
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
ElicА я в 12с могу. Хоть процедуру.

Код: plsql
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.
SQL> WITH
  2    FUNCTION with_function(p_num IN NUMBER) RETURN NUMBER IS
  3    BEGIN
  4      RETURN p_num;
  5    END;
  6  SELECT with_function(deptno)
  7  FROM   dept
  8  /

WITH_FUNCTION(DEPTNO)
---------------------
                   10
                   20
                   30
                   40

SQL> WITH
  2    FUNCTION with_function(p_num IN OUT NUMBER) RETURN NUMBER IS
  3    BEGIN
  4      RETURN p_num;
  5    END;
  6  SELECT with_function(deptno)
  7  FROM   dept
  8  /
SELECT with_function(deptno)
       *
ERROR at line 6:
ORA-06553: PLS-363: expression 'P0' cannot be used as an assignment target


SQL>



SY.
...
Рейтинг: 0 / 0
15.04.2017, 18:28
    #39439167
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> WITH
  2    FUNCTION get_param(p_param_name varchar2) return varchar2
  3    is
  4      i int;
  5      s varchar2(128);
  6    begin
  7      if dbms_utility.get_parameter_value(p_param_name, i, s) = 0 then
  8        return i;
  9      else
 10        return s;
 11      end if;
 12    end get_param;
 13  select get_param('compatible') from dual
 14  /

GET_PARAM('COMPATIBLE')
--------------------------------------------------------------------------
12.2.0

Код: plsql
1.
2.
3.
4.
  function get_parameter_value(parnam in     varchar2,
                               intval in out binary_integer,
                               strval in out varchar2,
                               listno in     binary_integer default 1)

...
Рейтинг: 0 / 0
15.04.2017, 22:17
    #39439206
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
Не понял? Завернуть функцию с out in/out параметрами в функцию с in параметрами и вызвать её из SQL можно хоть в Oracle 7. Ты бы привел пример вызова функции с out in/out параметрами из SQL напрямую.

SY.
...
Рейтинг: 0 / 0
15.04.2017, 23:11
    #39439216
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
SYНе понял?Это разные "задачи":
SYфункцию с OUT, IN/OUT параметрами вызвать из SQL.SYвызова функции с out in/out параметрами из SQL напрямую Поаккуратнее надо с категоричностью.
...
Рейтинг: 0 / 0
15.04.2017, 23:41
    #39439219
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
ElicПоаккуратнее надо с категоричностью.

Ты бы топик перечитал а не вырывал бы из контекста. А уж если "Поаккуратнее надо с категоричностью" то говорил я о вызове функции c out in/out параметрами ИЗ SQL а не ИЗ PL/SQL как в твоем примере.
...
Рейтинг: 0 / 0
16.04.2017, 07:22
    #39439245
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
SYя о вызове функции c out in/out параметрами ИЗ SQL а не ИЗ PL/SQL как в твоем примере.По твоей логике получается, что ниже вызов функции из PL/SQL?
Код: plsql
1.
for c in (select udf() from dual) loop ...
...
Рейтинг: 0 / 0
16.04.2017, 13:49
    #39439314
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
ElicПо твоей логике получается, что ниже вызов функции из PL/SQL?


Не прикидывайся. Ты ведь прекрасно понимаешь про SQL машину и про PL/SQL машину и про context switch и что подразумевается под вызовом UDF из SQL. Но уж если тебе так хочется, то пожалуйста - я буду "поаккуратнее надо с категоричностью" и уточню - вызов функции с out in/out параметрами из SQL предложения или, из SQL выражения (в документации используются оба термина).

SY.
...
Рейтинг: 0 / 0
16.04.2017, 15:43
    #39439336
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
Про rownum еще никто не сказал?
...
Рейтинг: 0 / 0
16.04.2017, 17:09
    #39439346
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
На днях материализовывал, материализовывал, но так и не выматериализовал
...
Рейтинг: 0 / 0
16.04.2017, 18:05
    #39439350
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
Да просто все такие функции надо объявлять детерминистик..
...
Рейтинг: 0 / 0
16.04.2017, 18:58
    #39439359
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
xtenderДа просто все такие функции надо объявлять детерминистик..

Ага, ообенно с SYSDATE .

SY.
...
Рейтинг: 0 / 0
16.04.2017, 19:46
    #39439363
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему функция вызывается 2 раза?
Да и не факт что поможет:

Код: plsql
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.
SQL> select banner from v$version
  2  /

BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
PL/SQL Release 12.1.0.1.0 - Production
CORE    12.1.0.1.0      Production
TNS for 64-bit Windows: Version 12.1.0.1.0 - Production
NLSRTL Version 12.1.0.1.0 - Production

SQL> CREATE  SEQUENCE sq_ttt;

Sequence created.

SQL> CREATE TYPE TYPE_DATA_QNT AS OBJECT (
  2           oper_date date,
  3           qnt0  number,
  4           qnt1  number,
  5           qnt2  number
  6  );
  7  /

Type created.

SQL> CREATE or replace
  2  function test_TYPE_DATA_QNT RETURN TYPE_DATA_QNT
  3  DETERMINISTIC
  4  IS
  5    v_sq integer;
  6  BEGIN
  7    v_sq :=  sq_ttt.nextval;
  8    RETURN  TYPE_DATA_QNT(sysdate,0,0,0);
  9  END;
 10  /

Function created.

SQL> SELECT sq_ttt.nextval FROM dual;

   NEXTVAL
----------
         1

SQL> SELECT v.dat.oper_date, v.dat.qnt0
  2  FROM
  3  (
  4      SELECT
  5        value(test_TYPE_DATA_QNT) as dat
  6      FROM dual
  7  ) v
  8  /

DAT.OPER_   DAT.QNT0
--------- ----------
16-APR-17          0

SQL> SELECT sq_ttt.currval FROM dual;

   CURRVAL
----------
         3

SQL>



SY.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Почему функция вызывается 2 раза? / 25 сообщений из 38, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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