Oracle
初級 PL/SQL:從動態 SQL 函式返回行值
我有一個成功編譯的 PL/SQL 函式:
01 WITH FUNCTION find_CV_errors( 02 l_table_name IN VARCHAR 03 ,l_field_name IN VARCHAR 04 ,l_domain_name IN VARCHAR 05 ) 06 RETURN VARCHAR 07 AS 08 l_return_value VARCHAR(128); 09 BEGIN 10 11 EXECUTE IMMEDIATE 12 'SELECT 13 LISTAGG(CAST(' || l_field_name || ' AS VARCHAR(50)), ' || '''; ''' || ') WITHIN GROUP (ORDER BY NULL) 14 FROM ' || 15 l_table_name || 16 ' LEFT JOIN 17 ( 18 SELECT CODE 19 FROM ENG.D_CV_ENG_VW 20 WHERE DOMAIN = :bv1 21 ) 22 ON ' || l_field_name || ' = code 23 WHERE ' || 24 l_field_name || ' IS NOT NULL 25 AND code IS NULL' 26 INTO l_return_value 27 USING l_domain_name; 28 RETURN l_return_value; 29 END;
該函式有一個動態 sql 查詢,通過 LISTAGG 在單行中輸出單列。
我希望函式將動態 sql 輸出作為返回值返回。但是,現在它只返回 NULL,因為我沒有為
l_return_value
變數賦值。如何將動態 SQL 查詢的輸出分配給
l_return_value
變數?更新#1:
我已添加
INTO l_return_value;
到查詢 (LINE 26
),但現在出現錯誤:
ORA-06553:PLS-103: Encountered the symbol "L_FIELD_NAME" when expecting one of the following: : = , ( @ % ;
更新#2:
當我從 末尾刪除分號時
line 26
,該函式返回 的值l_field_name
,而不是來自動態 sql 查詢輸出的值。更新#3:
除了 Balazs Papp 指出的錯誤之外,我還有一個綁定變數 on
line 13
,而實際上我應該使用連接變數。由於 Balazs Papp 的回答使用了通用範例,而不是問題的更正版本,因此我自己更正了原始問題(lines 07, 13, 26, 27, 28
)。
對於單行,使用
EXECUTE IMMEDIATE ... INTO
. 一個簡單的例子:set serveroutput on declare l_result number; begin execute immediate 'select count(*) from dual' into l_result; dbms_output.put_line(l_result); end; / 1
對於多行,請使用
EXECUTE IMMEDIATE .. BULK COLLECT INTO
,這是一個範例:https://stackoverflow.com/questions/21117021/bulk-collect-into-and-execute-immediate-in-oracle
declare type x is table of t.id%type index by pls_integer; xx x; begin execute immediate 'select id from t' bulk collect into xx; dbms_output.put_line(xx.count); end; /
好的,另一個例子,使用 12c WITH 函式:
with function f1 (p_a number) return number as l_result number; begin execute immediate 'select count(*) from dba_objects where object_id = :B1' into l_result using p_a; return l_result; end; select f1(object_id) from dba_objects where object_name = 'HELP'; / F1(OBJECT_ID) ------------- 1