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?
答案 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