扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
sqlplus或者PL/SQL
创新互联是专业的龙山网站建设公司,龙山接单;提供网站设计制作、网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行龙山网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
SQL窗口
输入(单独调用存储过程):
无参数
EXEC
过程名;
或者
BEGIN
过程名
END;
IN
参数
EXEC
过程名(入参数..);
或者
BEGIN
过程名(入参数...)
END;
OUT参数,IN
OUT参数
variable
绑定变量名
数据类型;
//定义一个变量接收出参数的值;
EXEC
过程名(:绑定变量名);
ORACLE存储过程 以oracle自带例子数据库的表举例
1、
create or replace procedure p
is
cursor c is
select * from emp2 for update;
begin
for v_emp in c loop
if(v_emp.sal 2000) then
update emp2 set sal =sal+1 where current of c ;
elsif(v_emp.sal=2000) then
delete from emp2 where current of c;
end if;
end loop;
commit;
end;
创建了存储过程不代表运行了存储过程;
运行此存储过程 :
方式一 exec p;
方式二
begin
p;
end;
2、带参数的存储过程
in 相当于程序里的参数,供传入用,在存储过程不能改变其值;
out 相当于程序里的返回值,在存储过程中可以为其赋值传出;
in out 既可以当参数又可以当返回值用;
不带上述说明符默认为in类型;
下例中v_a v_b 为in类型
v_c 为out类型
v_d 为in out 类型
create or replace procedure p(v_a in number,v_b number,v_c out number,v_d in out number)
is
begin
if(v_a v_b) then
v_c := v_a;
else
v_c := v_b;
end if;
v_d := v_d+1;
end;
--- 调试时:
可以在命令窗口调试,出错时 用show errors 显示出错信息;
可以在plDv中调试;
--- 运行时:
可以在命令窗口运行:
declare
v_a number:=3;
v_b number:=4;
v_c number;
v_d number:=5;
begin
p(v_a,v_b,v_c,v_d);
dbms_output.put_line(v_c);
dbms_output.put_line(v_d);
end;
可以在plDv中调试;
Oracle存储过程写法实例
总结项目中写的存储过程例子:
Oracle存储过程基本语法 存储过程
1 CREATE OR REPLACE PROCEDURE 存储过程名
2 IS/AS
3 BEGIN
4 NULL;
5 EXCEIPTION;
6 END;
1、创建存储过程,后面可用is或者as:
create or replace procedure PRO_COMPLAIN_TEMPLATE as
2、定义变量,此处用到了%TYPE和%ROWTYPE,参考 /database/201211/168564.html ,另外定义了一个游标,TEM_INSTANCE TEMPLATE_CUR%ROWTYPE这个类型定义必须要在游标定义之后:
NEED_DO_FOR_ZL INTEGER;
CURRENT_MAX_ID MEMO_TEMPLET.TEMPLET_ID%TYPE;
CURSOR TEMPLATE_CUR IS SELECT TEMPLET_NAME, TEMPLET_CONTENT FROM SYS_COMPLAINT_TEMPLET;
TEM_INSTANCE TEMPLATE_CUR%ROWTYPE;
3、begin开始块:
begin
4、该插入语句使用了DBLINK,还有使用DBMS_OUTPUT.put_line('打印信息')进行信息输出:
insert into MEMO_TEMPLET (TEMPLET_ID, TEMPLET_CONTENT, TEMPLET_TYPE, TEMPLET_MEMO) (SELECT * FROM MEMO_TEMPLET@COMPANY);
SELECT COUNT(*) INTO NEED_DO_FOR_ZL FROM SYS_COMPLAINT_TEMPLET;
IF(NEED_DO_FOR_ZL 0) THEN
DBMS_OUTPUT.put_line('打印信息');
SELECT MAX(TEMPLET_ID)+1 INTO CURRENT_MAX_ID FROM MEMO_TEMPLET;
DBMS_OUTPUT.put_line('MEMO_TEMPLET最大ID' || CURRENT_MAX_ID);
FOR TEM_INSTANCE IN TEMPLATE_CUR LOOP
INSERT INTO MEMO_TEMPLET (TEMPLET_ID, TEMPLET_CONTENT,
TEMPLET_TYPE, TEMPLET_MEMO) VALUES (CURRENT_MAX_ID,
TEM_INSTANCE.TEMPLET_CONTENT, '7', NULL);
CURRENT_MAX_ID := CURRENT_MAX_ID + 1;
DBMS_OUTPUT.put_line(TEM_INSTANCE.TEMPLET_CONTENT);
END LOOP;
END IF;
COMMIT;
4、exception块,使用WHEN OTHERS THEN,其中用raise可显示错误信息:
exception
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('sqlcode : ' ||sqlcode);
raise;
ROLLBACK;
IF TEMPLATE_CUR%ISOPEN THEN
CLOSE TEMPLATE_CUR;
END IF;
DBMS_OUTPUT.put_line('打印信息');
end;
注:关于游标的使用,如果像本例中使用for循环去遍历游标的话则不需要显式的去用open/close
cursor打开和关闭游标,此处会自己处理,如果使用fetch
into的话就需要显式开关游标,另外任意执行一个update操作,用隐式游标sql的属性%found,%notfound,%rowcount,%isopen观察update语句的执行情况,也可以使用来判断游标状态,如IF
TEMPLATE_CUR%ISOPEN THEN。
给你示例你参考下:
----------------------------建立存储过程:
CREATE OR REPLACE PROCEDURE P_name--存储过程名字
(
i_var in int, --输入参数1
o_var OUT varchar2 --输出参数1
)
IS
v_STR VARCHAR2(200); --定义存储过程内部的局部变量
BEGIN
--下面是存储过程的主体实现部分
v_STR := i_var;
dbms_output.put_line(v_STR);
o_var := v_STR;
exception--错误异常处理部分
when others then
dbms_output.put_line(sqlerrm);--打印错误信息
END P_name;
-----------------------------------调用存储过程示例:
declare
v_in int;
v_out varchar2(50);
begin
v_in :=100;
P_name (v_in,v_out); --调用存储过程P_name
dbms_output.put_line('存储过程输入结果为:'||v_out);
exception--错误异常处理部分
when others then
dbms_output.put_line(sqlerrm);--打印错误信息
end;
一:存储过程
创建存储过程,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系统权限
删除存储过程,是过程的创建者或者拥有DROP ANY PROCEDURE系统权限
修改存储过程,则只能是过程的创建者或者拥有ALTER ANY PROCEDURE系统权限的人
执行(或调用)存储过程,是过程的创建者或是拥有EXECUTE ANY PROCEDURE系统权限的人或是被拥有者授予EXECUTE权限的人
1:语法
1)创建
CREATE[ORREPLACE]PROCEDURE存储过程名[(参数[IN|OUT|INOUT] 数据类型...)]
{AS|IS}
[说明部分]
BEGIN
可执行部分
[EXCEPTION
错误处理部分]
END[过程名];
说明:
OR REPLACE 表示如果存在就覆盖存储过程
参数有三种形式:IN、OUT和IN OUT。则默认为IN。
关键字AS也可以写成IS,后跟过程的说明部分,可以在此定义过程的局部变量。
2)删除存储过程:
DROP PROCEDURE 存储过程名;
3)修改存储过程:
ALTER PROCEDURE 存储过程名 COMPILE;
4)执行存储过程
EXECUTE 模式名.存储过程名[(参数...)];
或
BEGIN
模式名.存储过程名[(参数...)];
END;
另外:参数可以是变量、常量或表达式
要其它用户执行存储过程须要给其它用户授权
GRANT EXECUTE ON 存储过程名 TO 用户名
2:参数说明
IN 定义一个输入参数变量,用于传递参数给存储过程
OUT 定义一个输出参数变量,用于从存储过程获取数据
IN OUT 定义一个输入、输出参数变量,兼有以上两者的功能
1)参数名 IN 数据类型 DEFAULT 值;
定义一个输入参数变量,用于传递参数给存储过程。
可以是常量、有值变量或表达式
DEFAULT 关键字为可选项,用来设定参数的默认值。如果在调用存储过程时不指明参数,则参数变量取默认值
在存储过程中,输入变量接收主程序传递的值,但不能对其进行赋值。
2)参数名 OUT 数据类型;
定义一个输出参数变量,用于从存储过程获取数据,即变量从存储过程中返回值给主程序。
在调用存储过程时,主程序的实际参数只能是一个变量,而不能是常量或表达式。
在存储过程中,参数变量只能被赋值而不能将其用于赋值,而且必须给输出变量至少赋值一次。
3)参数名 IN OUT 数据类型 DEFAULT 值;
定义一个输入、输出参数变量,兼有以上两者的功能。
在调用存储过程时,主程序的实际参数只能是一个变量,而不能是常量或表达式。
DEFAULT 关键字为可选项,用来设定参数的默认值。
在存储过程中,变量接收主程序传递的值,同时可以参加赋值运算,也可以对其进行赋值。在存储过程中必须给变量至少赋值一次。
补充:如果省略IN、OUT或IN OUT,则默认模式是IN。
调用它时参数个数与位置可以不一致,用以下形式调用:
EXECUTE CHANGE_SALARY(P_RAISE=80,P_EMPNO=7788); //=运算符左侧是参数名,右侧是参数表达式
二:函数
创建函数,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系统权限
删除函数,需要是函数的创建者或者是拥有DROP ANY PROCEDURE系统权限的人
修改函数,需要是函数的创建者或者拥有ALTER ANY PROCEDURE系统权限的人
执行函数,需要是函数的创建者或拥有EXECUTE ANY PROCEDURE系统权限的人
1:语法
1)创建:
CREATE[ORREPLACE]FUNCTION函数名[(参数[IN] 数据类型...)]
RETURN数据类型
{AS|IS}
[说明部分]
BEGIN
可执行部分
RETURN(表达式)
[EXCEPTION
错误处理部分]
END[函数名];
说明:
参数是可选的,但只能是IN类型(IN关键字可以省略)。
在定义部分的RETURN 数据类型,用来表示函数的数据类型,也就是返回值的类型,不可省略。
在可执行部分的RETURN(表达式),用来生成函数的返回值,其表达式的类型应该和定义部分说明的函数返回值的数据类型一致。在函数的执行部分可以有多个RETURN语句,但只有一个RETURN语句会被执行,一旦执行了RETURN语句,则函数结束并返回调用环境。
2)删除
DROP FUNCTION 函数名;
3)修改
ALTER PROCEDURE 函数名 COMPILE;
4)执行
变量名:=函数名(...)
三:对存储过程 和 函数的查看(可以通过对数据字典【USER_SOURCE】的访问来查询存储过程或函数的有关信息)
1:查询某个存储过程序内容
select TEXT from user_source WHERE NAME='存储过程名';
2:查看数据字殿
DESCRIBE USER_SOURCE ; //命令行中
3:查看存储过程的参数
DESCRIBE say_hello; //后面是过程名
4:查看发生编辑错误
SHOW ERRORS ;
5:查询一个存储过程或函数是否是有效状态(即编译成功)
SELECT STATUS FROM USER_OBJECTS WHERE OBJECT_NAME='过程名';//注意大小写
VALID表示该存储过程有效(即通过编译),INVALID表示存储过程无效或需要重新编译。它的状态会改变,这与它依赖外部表(表删除修改等操作)有关系
6:查看存储过程与表的依赖关系
SELECT REFERENCED_NAME,REFERENCED_TYPE FROM USER_DEPENDENCIES WHERE NAME='SAY_HELLO';
说明
NAME为实体名,TYPE为实体类型,REFERENCED_OWNER为涉及到的实体拥有者账户,REFERENCED_NAME为涉及到的实体名,REFERENCED_TYPE 为涉及到的实体类型。
问题:
如果一个用户A被授予执行属于用户B的一个存储过程的权限,在用户B的存储过程中,访问到用户C的表,用户B被授予访问用户C的表的权限,但用户A没有被授予访问用户C表的权限,那么用户A调用用户B的存储过程是失败的还是成功的呢?答案是成功的。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流