2010-07-06 8 views

Antwort

9

Sie können nicht. Natürlich sind Sie in Kontrolle, wie viel Daten Sie in den OUT-Parameter in der gespeicherten Prozedur eingeben. Wenn Sie möchten, können Sie eine große lokale Variable erstellen, um die Daten zu speichern, und dann den Wert dieser Variablen dem OUT-Parameter zuweisen.

Das aufrufende Programm bestimmt die Größe der Variablen, die den Parameter OUT empfängt.

0

Sie einen Subtyp in einem Paket-Header verwenden könnte, und geben Sie, dass im Körper prüfen ...

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; 
/

Dann, wenn Sie laufen diese

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

Sie würden den Fehler

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

Scheint, gegen den Geist der Verwendung eines Out-Parameters zu gehen, aber nach Tonys Kommentar war dies das einzige, was ich verdünnen konnte k von, um Daten innerhalb des aufgerufenen Codes zu steuern.

+0

Das dokumentiert die Absicht, aber es gelingt nicht, die Größe des zurückgegebenen Werts zu beschränken. Die Prozedur kann über pv_variable eine Zeichenfolge beliebiger Größe zurückgeben. –

+0

Ich habe immer Typ/Länge in meinem Code überprüft, so dass nie ein Out-Parameter (oder Funktionsrückgabe) keine Beschränkung auf die Rückgabegröße bemerkt. Guter Platz Tony. –

3

Hier ist ein einfaches Paket, das erklärt und verwendet einen Subtyp:

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> 

Wenn wir jedoch PAD_STRING() so nennen, dass die Ausgabezeichenfolge der Präzision Subtyp des übersteigt es immer noch erfolgreich abgeschlossen wurde. Mühe!

Das ist ärgerlich, aber es ist die Art wie PL/SQL funktioniert, also müssen wir damit leben.

Der Weg, um die Situation zu lösen, ist im Grunde zu gelten DBC principles und validieren Sie unsere Parameter.

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> 

Oder können wir Geschäftsregeln gegen die Ausgabe wie folgt behaupten: So können wir Geschäftsregeln gegen den Eingängen wie diese behaupten

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> 

In den meisten Szenarien sollten wir beides tun. Dies ist die höfliche Art, Schnittstellen zu erstellen, da dies bedeutet, dass andere Routinen unsere Prozeduren mit der Gewissheit aufrufen können, dass sie die Werte zurückgeben, die sie sagen.

Verwandte Themen