首页 > 数据库 > Oracle > Oracle Procedure I
/ SQLplus 中,设置 set serveroutput on 才能显示输出结果 /
--- 匿名的 PLSQL( 存储过程 ) 块,不存储在数据库中
|
1
2
3
4 |
beginnull
;end
;/ |
|
1
2
3
4
5 |
begindbms_output.put(
'hi '
); /*put是不换行的输出*/dbms_output.put_line(
'hello world'
); /*put_line是换行的输出*/end
;/ |
--- 命名的存储过程,存储在数据库中
|
1
2
3
4
5 |
create
or
replace
procedure
hello_procedure
asbeginnull
;end
hello_procedure;/ |
--- 存储过程里面可以直接执行 DML
|
1
2
3
4
5
6
7
8
9
10
11
12 |
create
table
test (id number,
name
varchar
(20));begininsert
into
test
values
(1,
'zmh'
);commit
;end
;/ begininsert
into
test
values
(2,
'qyt'
);commit
;end
;/ |
--- 存储过程中不能直接执行 select ,如果要执行 select ,必须跟上 into 字句
|
1
2
3
4 |
beginselect
*
from
test;end
;/ |
PLS-00428: 在此 SELECT 语句中缺少 INTO 子句
这个地方,我的理解是在存储过程中执行 select 语句,需要先把数据赋值到事先声明好的变量中,然后通过变量输出出来,一个列需要对应一个变量。
|
1
2
3
4
5
6
7 |
declarev_name varchar2(20);beginselect
name
into
v_name
from
test
where
id=1;dbms_output.put_line(v_name);end
;/ |
---select...into 只能赋值一行,不能赋值多行,如果赋值了不存在的行也会报错 ( 但可以处理 )
意思就是存储过程中, select 只能查一行 , 如下就会报错 , 提示超出请求行数:
|
1
2
3
4
5
6
7 |
declarev_name varchar2(20);beginselect
name
into
v_name
from
test;dbms_output.put_line(v_name);end
;/ |
ORA-01422: 实际返回的行数超出请求的行数
因此需要对 select 语句加 where 条件: where rownum<=1 或者 where id=1 。
下面是赋值了不存在的行的报错,及解决办法:
|
1
2
3
4
5
6
7 |
declarev_name varchar2(20);beginselect
name
into
v_name
from
test
where
id=3;dbms_output.put_line(v_name);end
;/ |
ORA-01403: 未找到任何数据
解决的小技巧是,写一个 union ,实际情况 union 空,将返回的值通过 max 函数筛选:
|
1
2
3
4
5
6
7
8
9
10 |
declarev_name varchar2(20);beginselect
max
(
name
)
into
v_name
from
(select
name
from
test
where
id=3unionselect
null
from
dual);dbms_output.put_line(v_name);end
;/ |
---select...into 多个列
虽然 select into 不能多个行,但是可以多个列:
|
1
2
3
4
5
6
7
8 |
declarev_id number;v_name varchar2(20);beginselect
id,
name
into
v_id,v_name
from
test
where
id=1;dbms_output.put_line(v_id||
','
||v_name);end
;/ |
--- 存储过程里面不能直接执行 DDL ,如果要执行 DDL ,可以使用动态 SQL(execute immediate)
|
1
2
3
4 |
beginalter
table
test
add
(tel varchar2(12));end
;/ |
PLS-00103: 出现符号 "ALTER" 在需要下列之一时 ....
解决办法;
|
1
2
3
4 |
beginexecute
immediate
'alter table test add(tel varchar2(12))'
;end
;/ |
--- 动态 SQL 里面不仅可以 DDL , DML 和 select...into 都可以
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013625/viewspace-3087074/ ,如需转载,请注明出处,否则将追究法律责任。