2010-07-06 17 views

回答

9

你不能。當然,你的在控制你存入多少數據到存儲過程中的OUT參數。如果您想要,您可以創建一個大小局部變量來保存數據,然後將該變量的值分配給OUT參數。

調用程序確定接收OUT參數的變量的大小。

0

你可以在一個包報頭使用亞型和類型檢查,在身體...

CREATE OR REPLACE PACKAGE my_test 
AS 
    SUBTYPE my_out IS VARCHAR2(10); 

    PROCEDURE do_something(pv_variable IN OUT my_out); 
END; 
/

CREATE OR REPLACE PACKAGE BODY my_test 
AS 
    PROCEDURE do_something(pv_variable IN OUT my_out) 
    IS 
     lv_variable my_out; 
    BEGIN 
     -- Work on a local copy of the variable in question 
     lv_variable := 'abcdefghijklmnopqrstuvwxyz'; 

     pv_variable := lv_variable; 
    END do_something; 

END; 
/

然後,當你運行該

DECLARE 
    lv_variable VARCHAR2(30); 
BEGIN 
    my_test.do_something(lv_variable); 
    DBMS_OUTPUT.PUT_LINE('['||lv_variable||']'); 
END; 
/

你會得到錯誤

ORA-06502: PL/SQL: numeric or value error: character string buffer too small 

似乎違背了使用out參數的精神,但在Tony的評論之後,這是我唯一能夠瘦身的東西k來控制被調用代碼中的數據。

+0

這表明意圖,但它不能成功地限制返回值的大小。該過程可以通過pv_variable返回任意大小的字符串。 – 2010-07-06 09:21:53

+0

我一直在我的代碼中輸入/長度檢查,所以從來沒有注意到out參數(或函數返回)對返回大小沒有限制。好點的Tony。 – 2010-07-06 13:19:39

3

下面是一個簡單的包,其中聲明並使用一個亞型:

SQL> create or replace package my_pkg as 
    2  subtype limited_string is varchar2(10); 
    3  procedure pad_string (p_in_str varchar 
    4       , p_length number 
    5       , p_out_str out limited_string); 
    6 end my_pkg; 
    7/

Package created. 

SQL> create or replace package body my_pkg as 
    2  procedure pad_string 
    3   (p_in_str varchar 
    4    , p_length number 
    5    , p_out_str out limited_string) 
    6  as 
    7  begin 
    8   p_out_str := rpad(p_in_str, p_length, 'A'); 
    9  end pad_string; 
10 end my_pkg; 
11/

Package body created. 

SQL> 

但是,如果我們在輸出字符串超過亞型的精度這樣的方式調用PAD_STRING(),它還是成功完成。煩!

SQL> var out_str varchar2(128) 
SQL> 
SQL> exec my_pkg.pad_string('PAD THIS!', 12, :out_str) 

PL/SQL procedure successfully completed. 

SQL> 
SQL> select length(:out_str) from dual 
    2/

LENGTH(:OUT_STR) 
---------------- 
       12 

SQL> 

這很煩人,但這是PL/SQL的工作方式,所以我們必須忍受它。

解決方案的基本方法是應用DBC principles並驗證我們的參數。因此,我們可以對這樣的投入斷言業務規則:

SQL> create or replace package body my_pkg as 
    2  procedure pad_string 
    3   (p_in_str varchar 
    4    , p_length number 
    5    , p_out_str out limited_string) 
    6  as 
    7  begin 
    8   if length(p_in_str) + p_length > 10 then 
    9    raise_application_error(
10      -20000 
11      , 'Returned string cannot be longer than 10 characters!'); 
12   end if; 
13   p_out_str := rpad(p_in_str, p_length, 'A'); 
14  end pad_string; 
15 end my_pkg; 
16/

Package body created. 

SQL> 
SQL> exec my_pkg.pad_string('PAD THIS!', 12, :out_str) 
BEGIN my_pkg.pad_string('PAD THIS!', 12, :out_str); END; 

* 
ERROR at line 1: 
ORA-20000: Returned string cannot be longer than 10 characters! 
ORA-06512: at "APC.MY_PKG", line 9 
ORA-06512: at line 1 


SQL> 

或者,我們可以對這樣的輸出斷言業務規則:

SQL> create or replace package body my_pkg as 
    2  procedure pad_string 
    3   (p_in_str varchar 
    4    , p_length number 
    5    , p_out_str out limited_string) 
    6  as 
    7   l_str limited_string; 
    8  begin 
    9   l_str := rpad(p_in_str, p_length, 'A'); 
10   p_out_str := l_str; 
11  end pad_string; 
12 end my_pkg; 
13/

Package body created. 

SQL> 
SQL> exec my_pkg.pad_string('PAD THIS!', 12, :out_str) 
BEGIN my_pkg.pad_string('PAD THIS!', 12, :out_str); END; 

* 
ERROR at line 1: 
ORA-06502: PL/SQL: numeric or value error: character string buffer too small 
ORA-06512: at "APC.MY_PKG", line 9 
ORA-06512: at line 1 

SQL> 

在我們應該做兩大部分場景。這是構建接口的禮貌方式,因爲這意味着其他例程可以調用我們的過程,並確信它們將返回它們表示的值。

相關問題