2017-05-08 58 views
0

我的測試功能是本如何運行返回多個值

CREATE OR REPLACE FUNCTION MULTI_VAL 
(MYNAME OUT EMP2017.ENAME%TYPE) 
RETURN NUMBER AS 
    MYSAL EMP2017.SAL%TYPE; 
BEGIN 
    SELECT SAL, ENAME INTO MYSAL, MYNAME FROM EMP2017 ; 
    RETURN MYSAL; 
END; 
/

當我運行它像

variable mynm varchar2(20) 

SELECT MULTI_VAL(:mynm) FROM dual; 

它給這個錯誤

ERROR at line 1:
ORA-06553: PLS-561: character set mismatch on value for parameter 'MYNAME'

+0

那麼什麼是'EMP2017.MYNAME'的數據類型? – APC

+0

假設它是'nvarchar2(20)',你有什麼數據庫和國家字符集?另外我期望查詢得到'ORA-06572:Function MULTI_VAL has out arguments',並且由於函數的查詢沒有過濾器,所以如果表中沒有完全一行,則會出錯。你真的想做什麼?也許你想要返回一個引用遊標或流水線集合? –

回答

2

Oracle的功能現在出現的錯誤表明數據類型不匹配。

但是,您的代碼存在一個基本問題。我們不能使用SQL中具有OUT參數的函數。所以一旦你解決了數據類型問題,你會得到這個錯誤:ORA-06572: Function MULTI_VAL has out arguments

您可以像這樣運行:

declare 
    n varchar2(20); 
    x number; 
begin 
    x := multi_val(n); 
end; 
/

一般來說,帶有輸出參數的功能被認爲是不好的做法。語法允許它們,但用法很難理解。最好使用帶有兩個OUT參數的過程(因爲我們只能在PL/SQL中調用程序),否則就會返回一個用戶定義的類型。

0
CREATE TABLE EMP2017(ENAME VARCHAR2(10),SAL NUMBER); 

INSERT INTO EMP2017 VALUES ('SMITH',5000); 
INSERT INTO EMP2017 VALUES ('JOHNS',1000); 

COMMIT; 

CREATE TYPE RET_MULT AS OBJECT 
(ENAME  VARCHAR2(10),SAL NUMBER); 

CREATE TYPE T_RET_MULT AS TABLE OF RET_MULT; 

CREATE OR REPLACE FUNCTION MULTI_VAL RETURN T_RET_MULT PIPELINED IS 
MYSAL RET_MULT; 
BEGIN 
FOR I IN(SELECT SAL, ENAME FROM EMP2017) LOOP 
    MYSAL := RET_MULT(I.ENAME,I.SAL); 
    PIPE ROW(MYSAL); 
END LOOP ; 
RETURN ; 
END; 

SELECT * FROM TABLE(MULTI_VAL()); 
+1

爲什麼在這個任務中使用管道功能?有必要嗎? – Seyran

+0

在該解決方案中,您可以獲得多列和多行 –

+0

我看到它,但可以在不進行流水線處理的情況下完成。 – Seyran

0

我想這個問題可以在不使用管道功能的情況下解決。像這樣。所有預先要求的數據如下所述@Satat.Turan函數除外。對不起,複製/過去。

CREATE TABLE EMP2017(ENAME VARCHAR2(10),SAL NUMBER); 

INSERT INTO EMP2017 VALUES ('SMITH',5000); 
INSERT INTO EMP2017 VALUES ('JOHNS',1000); 

COMMIT; 

CREATE TYPE RET_MULT AS OBJECT 
(ENAME  VARCHAR2(10),SAL NUMBER); 

CREATE TYPE T_RET_MULT AS TABLE OF RET_MULT; 
    create or replace function MULTI_VAL return T_RET_MULT is 
     RET_SET T_RET_MULT; 
    begin 

     select RET_MULT(ENAME, SAL) bulk collect into RET_SET from EMP2017; 

     return RET_SET; 
    end; 
+0

您說得對,流水線函數不是必需的,但這兩種解決方案都假定事情不在原始問題中。 – APC

+0

你爲什麼這麼認爲?我認爲這個解決方案正是問題所有者想要的。根據問題,我不認爲正確的答案將是錯誤解決。在選擇陳述中沒有條件,我不認爲在時間上只有一行,所以給出的答案更適合這個問題。 – Seyran