create or replace procedure pr
is
v_date date;
begin
select sysdate into v_date from dual;
DBMS_output.put_line(v_date);
end pr;
答案 0 :(得分:4)
SQL语句中不允许使用过程,因为混合声明性和命令式编程样式会让人感到困惑。
SQL语句是一个条件列表 - 由Oracle决定如何生成与这些条件匹配的结果集。 PL / SQL存储过程是一组以非常可预测的方式改变事物的指令。
在下面的示例中,pr
应执行多少次?它是在id = 1
之前还是之后执行的?如果SQL语句具有预定义的顺序,那么优化器将无法推送谓词,合并子查询等,并且性能将是不可接受的。
select *
from table1
where id = 1
and pr;
即使在select
列表中使用过程,也可能没有意义。例如,select
内的exists
列表始终被忽略。
select * from dual where exists (select pr from dual);
但实际上SQL语句有时需要与外界进行交互,并且需要一些程序逻辑。允许使用函数,因为它们通常只是计算某些东西并返回一个值。功能通常不依赖于程序状态,并且有很多副作用。您的函数可以使用会话变量,更新表(如果它设置为PRAGMA AUTONOMOUS TRANSACTION
),设置上下文等.Oracle不能阻止您做这些事情,但禁止SQL中的过程声明至少会阻止这样的代码。
答案 1 :(得分:1)
无法使用select语句执行过程,如果要使用select语句执行,可以使用函数。
如果你想使用select语句执行过程,那么一种方法是使用函数包装你的过程并使用select语句调用函数。
CREATE OR REPLACE PROCEDURE pr (o_param OUT DATE)
IS
v_date DATE;
BEGIN
SELECT SYSDATE
INTO v_date
FROM DUAL;
o_param := v_date;
END pr;
现在用函数
包装过程CREATE OR REPLACE FUNCTION my_funct
RETURN DATE
AS
o_param DATE;
BEGIN
pr (o_param);
RETURN o_param;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line (
DBMS_UTILITY.format_error_backtrace || ' ' || SQLERRM
);
-- raise exception
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
DBMS_UTILITY.format_error_backtrace || ' ' || SQLERRM
);
-- raise exception
END my_funct;
/
使用select语句
调用该函数SELECT my_funct FROM DUAL
答案 2 :(得分:0)
CREATE OR REPLACE PROCEDURE count_salas IS V_count NUMBER(3);
BEGIN
SELECT COUNT(SALES.SALEQTY) as sales INTO V_count
FROM SALES INNER JOIN EMPLOYEE ON EMPLOYEE.EMPID = SALES.EMPID WHERE EMPLOYEE.EMPID = '101';
DBMS_OUTPUT.PUT_LINE(V_count); END V_count;