Calling a PLSQL subprogram from within SQL

时间:2016-10-20 13:21:20

标签: oracle plsql

From within an Oracle stored procedure, is it possible to call a subprogram from within a SQL statement? Perhaps an example would be a better way to explain it. Here is a straightforward example:

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

However, this results in an ORA-00904 error. So, I'm not confidant the answer to my question will be yes. Nevertheless, I still wanted to ask.

What my real program is trying to do is compare over a hundred pairs of fields. So, something like this:

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

So, if perhaps what I am trying is not possible, is there a better way to accomplish my end-goal?

2 个答案:

答案 0 :(得分:0)

你可以这样简单地调用一个程序:

  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

如果要使用函数在SQL语句中调用,这是一种方式:

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>

答案 1 :(得分:0)

如果您想使用变量,则必须在声明任何内联函数/过程之前声明它们。

这个有效:

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;

但这个不起作用:

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