简体   繁体   English

Oracle 如何使用循环动态更改函数中的参数/参数

[英]Oracle How to Dynamicaly change argument/parameter in function with loop

How to dynamicaly change argument/parameter in pipeline function with loop?如何使用循环动态更改管道函数中的参数/参数? Here is the example.这是示例。

CREATE OR REPLACE FUNCTION TESTES(
P_VALUE1 VARCHAR2,
P_VALUE2 VARCHAR2,
P_VALUE3  VARCHAR2 
)RETURN VARCHAR2

PIPELINED
AS
L_DYNM VARCHAR2(1000);
L_QUERY VARCHAR2(1000);
L_RETURN VARCHAR2(1000);

BEGIN
FOR i IN 1..3 LOOP
    L_DYNM := 'P_VALUE' || i || ',';
END LOOP;

L_QUERY := 'SELECT' || L_DYNM ||'FROM DUAL';


/* SELECT SME_PACE.SYS_REGEX_DEBIT(P_VALUE) INTO L_RETURN FROM DUAL; */
FOR V_REC IN (
    EXECUTE IMMEDIATE L_QUERY
        INTO L_RETURN
)
LOOP
    PIPE ROW (
        OBJECT_TESTES(
            V_REC.FIELD1, V_REC.FIELD2, V_REC.FIELD3
    );
END LOOP;
END;

So what i want to try to do actually is run SELECT P_VALUE1, P_VALUE2, P_VALUE3 From dual Dynamically and use it on pipeline row.所以我实际上想要尝试做的是从双动态运行SELECT P_VALUE1, P_VALUE2, P_VALUE3并在管道行上使用它。

Theres a reason why i have to do it like that, i need an answer is it possible doing it like this?我必须这样做是有原因的,我需要一个答案是否可以这样做? so i can apply it on my project.所以我可以将它应用到我的项目中。

Thanks谢谢

You have lots of inconsistencies in your function:您的功能有很多不一致之处:

  • The return type is VARCHAR2 but you are trying to use a PIPELINE that would return a collection.返回类型是VARCHAR2但您正在尝试使用将返回集合的PIPELINE
  • You are overwriting the value of L_DYNM each iteration of the loop.您将在循环的每次迭代中覆盖L_DYNM的值。
  • You are trying to select three dynamic column names from the DUAL table when it only has a single DUMMY column.DUAL表只有一个DUMMY列时,您正试图从DUAL表中选择三个动态列名。

Then you have syntax errors:然后你有语法错误:

  • Unmatched closing brackets.无与伦比的右括号。
  • EXECUTE IMMEDIATE inside a FOR statement.FOR语句中EXECUTE IMMEDIATE

You probably want something like:你可能想要这样的东西:

CREATE TYPE object_testes IS OBJECT(
  a VARCHAR2(100),
  b VARCHAR2(100),
  c VARCHAR2(100)
);

CREATE TYPE object_testes_table IS TABLE OF object_testes;
CREATE OR REPLACE FUNCTION TESTES(
  P_VALUE1 VARCHAR2,
  P_VALUE2 VARCHAR2,
  P_VALUE3  VARCHAR2 
) RETURN object_testes_table PIPELINED
AS
  p_cur SYS_REFCURSOR;
  p_sql VARCHAR2(4000);
  p_field1 VARCHAR2(100);
  p_field2 VARCHAR2(100);
  p_field3 VARCHAR2(100);
BEGIN
  p_sql := 'SELECT ' || DBMS_ASSERT.ENQUOTE_NAME( p_value1 ) || ', '
                     || DBMS_ASSERT.ENQUOTE_NAME( p_value2 ) || ', '
                     || DBMS_ASSERT.ENQUOTE_NAME( p_value3 ) || ' '
           || 'FROM DUAL';

  OPEN p_cur FOR p_sql;

  LOOP
    FETCH p_cur INTO p_field1, p_field2, p_field3;
    EXIT WHEN p_cur%NOTFOUND;
    PIPE ROW (
      OBJECT_TESTES(
        p_field1,
        p_field2,
        p_field3
      )
    );
  END LOOP;

  CLOSE p_cur;
END;
/

Then:然后:

SELECT * FROM TABLE( testes( 'DUMMY', 'DUMMY', 'DUMMY' ));

Outputs:输出:

\nA |一个 | B |乙 | C C \n:- | :- | :- | :- | :- :-\nX | X | X | X | X X \n

db<>fiddle here db<> 在这里摆弄

Try the following way.试试下面的方法。 This will do the same thing but without using select P_Value1 dual .这将做同样的事情,但不使用select P_Value1 dual

Create Object:创建对象:

CREATE TYPE sample_record AS OBJECT (P_VALUE1 VARCHAR2(10),
P_VALUE2  VARCHAR2(10),
P_VALUE3  VARCHAR2(10)
);/

Then Create array of created object.然后创建创建对象的数组。

CREATE TYPE sample_records IS TABLE OF sample_record; /

Function to convert object into Pipe Row:将对象转换为管道行的函数:

CREATE OR REPLACE FUNCTION test (P_VALUE1 VARCHAR2,P_VALUE2 VARCHAR2,P_VALUE3  VARCHAR2) 
RETURN sample_records PIPELINED AS
     BEGIN
               PIPE ROW(sample_record(P_VALUE1,P_VALUE2,P_VALUE3));    
     RETURN;
END;
/

Then call the above function in the following way.然后按照下面的方式调用上面的函数。 You call it in the loop also:您也可以在循环中调用它:

select * from table(test('A','B','C'));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM