2016-12-16 2 views
1

Я пытаюсь вызвать функцию в выражении select. Это не сработало, и я прошу о помощи.вызов функции в выражении select в PL/SQL

Следующий код, как, например, и будет работать в пакете:

ФУНКЦИЯ:

Function sum_val(val1 in NUMBER, val2 in NUMBER) return float is 

    u float; 
BEGIN 

    u := (val2+ val1)/100;   

    return u; 

END sum_val; 

ЗЕЬЕСТ:

PROCEDURE xy_prc(pi_table_in IN VARCHAR2) IS 

BEGIN 

sql_stmt := 'CREATE TABLE AS tbx 
      SELECT 
      t.*, '|| sum_val(t.val1, t.val2) ||' AS Val3 
      FROM '|| pi_table_in ||' t'; 

EXECUTE IMMEDIATE sql_stmt; 

END; 

Проблема здесь:

'|| sum_val(t.val1, t.val2) ||' AS Val3 

В этом случае я должен объявить t.val1, t.val2, а их значения из инструкции SELECT не будут заменены.

Это также не работал:

'|| sum_val('t.val1', 't.val2') ||' AS Val3 

В этом случае 't.val1', 't.val2' будут значения (струнные)!

Это можно назвать этой функцией оператором SELECT?

Большое спасибо за ваши ответы!

+0

Почему нет: ... '' t. *, Sum_val (t.val1, t.val2) AS Val3'' ... позволяет функции вызываться как часть выбора в динамическом SQL? почему любой '||' вообще? – xQbert

+0

Не работает. ORA-00904 – Basti

ответ

2

Кажется мне, что вы пытаетесь слишком трудно: P

вы не можете просто позволить функцию назвать в то время, динамический запрос выполняет?

PROCEDURE xy_prc(pi_table_in IN VARCHAR2) IS 

BEGIN 

sql_stmt := 'CREATE TABLE tbx AS 
      SELECT t.* 
        , sum_val(t.val1, t.val2) AS Val3 
      FROM '|| pi_table_in ||' t'; 

EXECUTE IMMEDIATE sql_stmt; 

END; 
+0

Это правильно :) .. Когда я пытаюсь это сделать, я получаю сообщение об ошибке: ORA-00904. – Basti

+0

Итак, существует ли val1 и val2 в переменной pi_table_in, определяющей таблицу? Я догадываюсь! oh ... и не следует ли создавать таблицу tbx, поскольку не создавать таблицу как tbx, когда вы пытаетесь создать таблицу из select? – xQbert

+0

Да. Пытается вызвать функцию с реальными значениями, такими как sum_val (333, 555) AS Val3, также получая ORA-00904! :( – Basti

1

Проблема с кодом является то, что вы не можете определить функцию SUM_VAL как функция пакета, если вы хотите использовать его в SQL запросе. Он должен быть создан в схеме.

create or replace Function sum_val(val1 in NUMBER, val2 in NUMBER) return float is 

     u float; 
    BEGIN 

     u := (val2+ val1)/100;   

     return u; 

    END sum_val; 

Конечно, ваша процедура может быть в упаковке. См. Исправленный синтаксис ниже

procedure xy_prc(pi_table_in in varchar2) is 
sql_stmt varchar2(1000); 
BEGIN 

sql_stmt := ' create table tbx as SELECT 
      t.*, sum_val(t.val1, t.val2) as Val3 
      FROM '|| pi_table_in ||' t'; 

EXECUTE IMMEDIATE sql_stmt; 

END; 
0

Большое спасибо за ваши ответы!

Решение должно быть очень простым. Я могу вызвать функцию COUNT() из любого DDL-скрипта, функции или пакета. Моя функция «sum_val()» может быть вызвана только в моем пакете.

Как сказал Мина, функция должна быть создана следующим образом:

create or replace Function... 

, чтобы быть в состоянии назвать в SQL-даного как функции COUNT(), как Select count(*) from tb или любой другой функции SQL.

Проблема заключается в том, что функция (создание или замена функции) будет доступна в схеме и может быть вызвана из любого пакета или DDL-скрипта. Я хотел создать частную функцию, которую можно вызывать только из Пакета.

Мое решение заключается в следующем: функция должна быть объявлена ​​как общественного объекта в пакете, например:

CREATE PACKAGE test AS 
    PROCEDURE xy_prc(pi_table_in in varchar2); 
    Function sum_val(val1 in NUMBER, val2 in NUMBER) return float; 
END test; 
/


CREATE OR REPLACE PACKAGE BODY test AS 

    Function sum_val(val1 in NUMBER, val2 in NUMBER) return float is 

     u float; 
    BEGIN 

     u := (val2+ val1)/100;   

     return u; 

    END sum_val; 

    procedure xy_prc(pi_table_in in varchar2) is 
     sql_stmt varchar2(1000); 
    BEGIN 

     sql_stmt := ' create table tbx as SELECT 
       t.*, test.sum_val(t.val1, t.val2) as Val3 
       FROM '|| pi_table_in ||' t'; 

     EXECUTE IMMEDIATE sql_stmt; 

    END xy_prc; 

END test; 
/

с этим способом я могу вызвать функцию test.sum_val(t.val1, t.val2) в любой SQL-Постулаты внутри упаковки.