2016-10-20 13 views
0

Aus einer gespeicherten Oracle-Prozedur heraus ist es möglich, ein Unterprogramm innerhalb einer SQL-Anweisung aufzurufen? Vielleicht wäre ein Beispiel ein besserer Weg, es zu erklären. Hier ein einfaches Beispiel:Aufrufen eines PLSQL-Unterprogramms innerhalb von SQL

DECLARE 
    PROCEDURE p_test(in_text VARCHAR2) IS 
    BEGIN 
    dbms_output.put_line(in_text); 
    END; 
BEGIN 
    SELECT p_test('Test') FROM dual; 
END; 
/

Dies führt jedoch zu einem ORA-00904-Fehler. Also, ich bin nicht sicher, die Antwort auf meine Frage wird ja sein. Trotzdem wollte ich noch fragen.

Was mein wirkliches Programm zu tun versucht, ist über hundert Paar Felder zu vergleichen. So etwas wie folgt aus:

DECLARE 
    PROCEDURE p_compare 
    (in_old VARCHAR2, in_new VARCHAR2) IS 
    BEGIN 
    IF in_old <> in_new THEN 
     dbms_output.put_line('Mismatch'); 

     INSERT INTO tbl_mismatch VALUES (in_old, in_new); 
    END IF; 
    END; 

v_old_value_a VARCHAR2(30); 
v_new_value_a VARCHAR2(30); 
v_old_value_b VARCHAR2(30); 
v_new_value_b VARCHAR2(30); 

BEGIN 
--What I would like to do 
SELECT p_compare(old_value_a, new_value_a), p_compare(old_value_b, new_value_b) 
FROM (SELECT 'ALPHA' old_value_a, 'ALPHA' new_value_a, 'BETA' old_value_b, 'DELTA' new_value_b FROM dual); 

--What I am currently doing 
--I have over 100 pairs of fields that I am comparing 
--Declaring two variables for each pair becomes cumbersome 
SELECT old_value_a, new_value_a, old_value_b, new_value_b 
INTO v_old_value_a, v_new_value_a, v_old_value_b, v_new_value_b 
FROM (SELECT 'ALPHA' old_value_a, 'ALPHA' new_value_a, 'BETA' old_value_b, 'DELTA' new_value_b FROM dual); 

p_compare(v_old_value_a, v_new_value_a); 
p_compare(v_old_value_b, v_new_value_b); 
END; 
/

Also, wenn vielleicht das, was ich versuche, nicht möglich ist, gibt es einen besseren Weg, um mein End-Ziel zu erreichen?

+2

Sie eine Funktion aufrufen können, die Art und Weise, kein procedure.What Sie erwarten Sie SELECT p_test (‘ Test ') VON Dual'? – Aleksej

+0

Aleksej, für die Zwecke des Beispiels würde ich erwarten, dass SELECT p_test ('Test') FROM dual 'dasselbe zurückgibt wie' p_test ('Test') '. Im eigentlichen Code führt das Unterprogramm den Vergleich und einige zusätzliche Operationen durch und fügt die abweichenden Werte in eine Tabelle ein. – sukach

+0

Wenn p_test eine Prozedur ist, gibt es überhaupt nichts zurück; Wenn Sie ein Ergebnis erhalten möchten, müssen Sie eine Funktion erstellen, die einen Wert zurückgibt. – Aleksej

Antwort

0

Sie einfach eine Prozedur auf diese Weise anrufen:

SQL> DECLARE 
    2  PROCEDURE p_compare(in_old VARCHAR2, in_new VARCHAR2) IS 
    3  BEGIN 
    4   IF in_old <> in_new 
    5   THEN 
    6    DBMS_OUTPUT.put_line('Mismatch'); 
    7 
    8    INSERT INTO tbl_mismatch 
    9     VALUES (in_old, in_new); 
10   END IF; 
11  END; 
12 BEGIN 
13  p_compare('AA', 'BB'); 
14  p_compare('XX', 'XX'); 
15 END; 
16/
Mismatch 

PL/SQL procedure successfully completed. 

SQL> select * from tbl_mismatch; 

IN_OLD       IN_NEW 
------------------------------ ------------------------------ 
AA        BB 

Wenn Sie eine Funktion aufrufen, innerhalb einer SQL-Anweisung verwenden würde, dies ist ein Weg:

SQL> CREATE OR REPLACE FUNCTION f_compare(in_old VARCHAR2, in_new VARCHAR2) 
    2  RETURN VARCHAR2 IS 
    3 BEGIN 
    4  IF in_old <> in_new 
    5  THEN 
    6   RETURN 'Mismatch'; 
    7  ELSE 
    8   RETURN 'Match'; 
    9  END IF; 
10 END; 
11/

Function created. 

SQL> DECLARE 
    2  v_compare_result1      VARCHAR2(30); 
    3  v_compare_result2      VARCHAR2(30); 
    4 BEGIN 
    5  SELECT f_compare(old_value_a, new_value_a), f_compare(old_value_b, new_value_b) 
    6  INTO v_compare_result1, v_compare_result2 
    7  FROM (SELECT 'ALPHA' old_value_a, 
    8      'ALPHA' new_value_a, 
    9      'BETA' old_value_b, 
10      'DELTA' new_value_b 
11    FROM DUAL); 
12 
13  DBMS_OUTPUT.put_line('Compare 1: ' || v_compare_result1); 
14  DBMS_OUTPUT.put_line('Compare 2: ' || v_compare_result2); 
15 END; 
16/
Compare 1: Match 
Compare 2: Mismatch 

PL/SQL procedure successfully completed. 

SQL> 
+0

Aber ich ziehe die Werte, die aus einer Tabelle verglichen werden müssen. Ich würde es vorziehen, nicht zwei Variablen für jedes zu vergleichende Feld deklarieren zu müssen. In meinem Beispiel habe ich v_old_value_a/b. Stellen Sie sich v_ [alt/neu] _value_ [01-99] vor. – sukach

+0

Vielleicht ist die Funktion der beste Weg zu gehen. Sieht so aus, als würde ich nur eine Variable pro Vergleich brauchen, im Gegensatz zu zwei. – sukach

+0

Rate-Funktion funktioniert nicht, wenn es in der Prozedur eingebettet ist, wie ich mit dem Unterprogramm gehofft hatte. Ich arbeite mit einer Anbieter-App, daher bin ich etwas eingeschränkt. – sukach

0

Wenn Sie verwenden Variablen, die Sie deklarieren müssen, bevor Sie eine Inline-Funktion/Prozedur deklarieren.

Dieses funktioniert:

DECLARE 

    x NUMBER; 

    PROCEDURE p_test(in_text VARCHAR2) IS 
    BEGIN 
     DBMS_OUTPUT.PUT_LINE(in_text); 
    END; 

    FUNCTION give_me_five RETURN NUMBER IS 
    BEGIN 
     RETURN 5; 
    END; 

BEGIN 
    x := give_me_five; 
    DBMS_OUTPUT.PUT_LINE(x); 

    p_test('Hello World'); 
END; 

aber dieses nicht funktioniert:

DECLARE 

    FUNCTION give_me_five RETURN NUMBER IS 
    BEGIN 
     RETURN 5; 
    END; 

    x NUMBER; 

BEGIN 
    x := give_me_five; 
    DBMS_OUTPUT.PUT_LINE(x); 
END; 

ORA-06550: line 7, column 2: 
PLS-00103: Encountered the symbol "X" when expecting one of the following: 

    begin function pragma procedure 
ORA-06550: line 13, column 4: 
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: 

    end not pragma final instantiable order overriding static 
    member constructor map 
Verwandte Themen