Inceptor支持部分PL/SQL。
声明变量,赋予默认值,及赋值语句
declare
a string := 'a1'
b int default 1
begin
dbms_output.put_line('a in block 1: ' || a)
dbms_output.put_line('b in block 1: ' || b)
a := 'a2'
b := 2
dbms_output.put_line('a in block 1: ' || a)
dbms_output.put_line('b in block 1: ' || b)
end;
输出结果为:
a in block 1: a1
b in block 1: 1
a in block 1: a2
b in block 1: 2
declare
a string := 'a1'
begin
declare
b string := 'b1'
begin
dbms_output.put_line('a in block 1.1: ' || a)
dbms_output.put_line('b in block 1.1: ' || b)
end b1
dbms_output.put_line('a in block 1.1: ' || a)
--dbms_output.put_line('b in block 1.1: ' || b) 当去掉这一行注释时,有异常 java.lang.NullPointerException
end;
最简单的匿名块: BEGIN put_line( "Hello" ); END;
declare
a string := 'a1'
begin
dbms_output.put_line('a in block 1: ' || a)
declare
b string := 'b1'
begin
dbms_output.put_line('a in block 1.1: ' || a)
dbms_output.put_line('b in block 1.1: ' || b)
end b1
end;
输出结果为:
a in block 1: a1
a in block 1.1: a1
b in block 1.1: b1
create or replace procedure test(arg int) is
begin
put_line('hello world ' || arg)
end;
begin
test(5)
end;
示例:
create or replace procedure collection_get_test(arg int)
is
declare
type t_intc is table of arg%type
v_idc t_intc
v_valuec t_intc
v_id int
v_value int
begin
select id, value bulk collect into v_idc, v_valuec from t1 as t1
dbms_output.put_line(v_idc(arg) || " " || v_valuec(arg))
if v_idc(arg) is not null and v_valuec(arg) is not null then
v_id := v_idc(arg)
v_value := v_valuec(arg)
v_idc(arg) := v_idc(arg) - 1
v_valuec(arg) := v_valuec(arg) - 1
dbms_output.put_line(v_idc(arg) || " " || v_valuec(arg))
select id, value into v_idc(arg), v_valuec(arg) from t1 as t1 where id = v_id and value = v_value
dbms_output.put_line(v_idc(arg) || " " || v_valuec(arg))
end if
end
;
begin
collection_get_test(0)
collection_get_test(1)
collection_get_test(2)
end;
create or replace procedure record_test() is i_v int type rec_t is record(id i_v%type, value string) rec_v rec_t begin rec_v.id := 0 rec_v.value := "value" put_line(rec_v.id || " " || rec_v.value) select id as id, to_char(value) as value into rec_v from t1 where id = 10 put_line(rec_v.id || " " || rec_v.value) end ; begin record_test() end; transwarp -t -h localhost -f test.sql
create or replace procedure cursor_proc(arg int)
is
declare
v_id int
v_value int
cursor cur(cur_arg int)
is
select from (select from t1 where id < cur_arg)
begin
open cur(arg)
<<cur_loop1>>
loop
fetch cur into v_id, v_value
dbms_output.put_line(v_id || ' ' || v_value)
exit when cur%notfound
end loop cur_loop1
close cur
open cur(arg)
<<cur_loop2>>
loop
fetch cur into v_id, v_value
dbms_output.put_line(v_id || ' ' || v_value)
exit when cur%notfound
end loop cur_loop2
end;
begin
cursor_proc(12)
end;
create or replace procedure named_notation(arg1 in int default 10, arg2 in int default 20, arg3 int default null, arg4 int default 40) is
begin
put_line("arg1 = " || arg1 || ", arg2 = " || arg2 || ", arg3 = " || arg3 || ", arg4 = " || arg4 || ".")
return
end;
declare
val1 int
val2 int
val3 int
val4 int
begin
val1 := 0
val2 := 1
val3 := 2
val4 := 3
named_notation(arg1 => val1, arg2 => val2, arg3 => val3, arg4 => val4)
named_notation(arg4 => val1, arg3 => val2, arg2 => val3, arg1 => val4)
named_notation(arg2 => val2, arg4 => val4)
named_notation(arg2 => val4, arg4 => val2)
named_notation(val4)
named_notation()
end;
Syntax #1: IF-THEN
IF condition THEN
{...statements...}
END IF;
Syntax #2: IF-THEN-ELSE
IF condition THEN
{...statements...}
ELSE
{...statements...}
END IF;
Syntax #3: IF-THEN-ELSIF
IF condition THEN
{...statements...}
ELSIF condition THEN
{...statements...}
ELSE
{...statements...}
END IF;
示例:
declare
var int
begin
var := 1
if var = 1 then
put_line("Label print hit on var = " || var || ".")
var := var + 1
end if
end;
declare
var int
begin
var := 1
<<print>>
put_line("Label print hit on var = " || var || ".")
if var < 5 then
var := var + 1
goto print
end if
end;
declare
var int
begin
var := 1
<<simple_loop>>
loop
put_line("Simple loop body " || var || ".")
var := var + 1
exit simple_loop when var = 5
end loop simple_loop
end;
declare
cursor cur(cur_arg int) is
select * from t1 where id < cur_arg
begin
for for_var in 0..3 loop
put_line(for_var)
end loop
for for_var in 3 ..0 loop
put_line(for_var)
end loop
for for_var in reverse 0.. 3 loop
put_line(for_var)
end loop
for for_rec in cur(12) loop
put_line(for_rec.id || " " || for_rec.value)
end loop
--Re-loop the cursor without closing it,
--the last for loop should have done closing.
for for_rec in cur(12) loop
put_line(for_rec.id || " " || for_rec.value)
end loop
end;
declare
type rec_t is record(id int, value int)
type cr_t is table of rec_t
cr_v cr_t
begin
put_line("Select into...")
select * bulk collect into cr_v from t1 as t1
put_line("Forall 1...")
forall forall_v in 1..1
select * from t1 where id = cr_v(forall_v).id and value = cr_v(forall_v).value
put_line("Forall 2...")
forall forall_v in 1..2
select * from t1 where id = cr_v(forall_v).id and value = cr_v(forall_v).value
end;
declare
var int
begin
var := 1
while var != 5
loop
put_line("While loop body " || var || ".")
var := var + 1
end loop
end;
declare
var1 int
var2 int
begin
var1 := 1
<<outer_loop>>
loop
var2 := 1
put_line("Outer loop body " || var1)
var1 := var1 + 1
<<inner_loop>>
loop
continue outer_loop when var1 = 2
put_line("Inner loop body " || var2)
var2 := var2 + 1
exit inner_loop when var2 = 3
end loop
end loop outer_loop
end;
declare
var1 int
var2 int
begin
var1 := 1
loop
var2 := 1
put_line("Outer loop body " || var1)
var1 := var1 + 1
exit when var1 = 3
end loop outer_loop
end;
create or replace procedure dynamic_sql_test(tab string, id int, value int) is
declare
i_var int := 0
begin
put_line('Selecting from ' || tab)
execute immediate ' select * from (select * from ' || tab || ' where id = :v1 and value = :v2)' using in id, out value
execute immediate ' begin select count(*) into :v from ' || tab || ' where id = :v1 and id < :V1 + 1 and value = :v2 end' using out i_var, id, in value
end;
begin
dynamic_sql_test('t1', 10, 100)
dynamic_sql_test('t2', 20, 200)
end;
declare
m int := 2
cursor c is select * from t1 as t
type t is record(id int, value int)
r t
begin
loop
if !c%isopen then
open c
end if
fetch c into r
put_line(r.id % m || ' ' || r.value % m)
exit when c%notfound
end loop
end;
cursor基本操作二declare
type t_c is table of int not null
type t_r is record(id int, value int)
type t_cr is table of t_r
v_cid t_c
v_cvalue t_c
v_cr t_cr
cursor cur(cur_arg int)
is
select * from t1 where id < cur_arg
begin
open cur(arg)
<<cur_loop>>
loop
fetch cur bulk collect into v_cid, v_cvalue limit 10
put_line(v_cid.count() || " " || v_cvalue.count())
put_line(v_cid(1) || " " || v_cvalue(1))
exit when cur%notfound
end loop cur_loop
end
declare type t_c is table of int not null type t_r is record(id int, value int) type t_cr is table of t_r v_cid t_c v_cvalue t_c v_cr t_cr begin select id, value bulk collect into v_cid, v_cvalue from t1 where id < arg put_line(v_cid.count() || " " || v_cvalue.count()) put_line(v_cid(1) || " " || v_cvalue(1)) select * bulk collect into v_cr from t1 where id < arg put_line(v_cr.count()) put_line(v_cr(1).id || " " || v_cr(1).value) end;
create or replace procedure implicit_cursor_test(arg int)
is
begin
dbms_output.put_line('Loop 1...')
for v_rec in (select from t1 where id = arg) loop
dbms_output.put_line('v_rec: ' || v_rec.id || ' ' || v_rec.value)
dbms_output.put_line('Selecting...')
select from (select from t1 where id = v_rec.id)
end loop a
end;
begin
implicit_cursor_test(10)
end;
create or replace procedure dynamic_sql_test(tab string, id int, value int) is
declare
i_var int := 0
begin
dbms_output.put_line('Selecting from ' || tab)
execute immediate ' select from (select from ' || tab || ' where id = :v1 and value = :v2)' using in id, out value
execute immediate ' begin select count() into :v from ' || tab || ' where id = :v1 and id < :V1 + 1 and value = :v2 end' using out i_var, id, in value
dbms_output.put_line(tab || ' count: ' || i_var)
end;
declare
tab_prefix string := 't'
tab_id string := '3'
begin
dynamic_sql_test('t1', 10, 100)
dynamic_sql_test('t2', 20, 200)
execute immediate ' create table :tab as select from (select from t1)' using tab_prefix || tab_id
execute immediate ' select from ' || tab_prefix || tab_id
execute immediate ' truncate table :tab' using tab_prefix || tab_id
execute immediate ' select from ' || tab_prefix || tab_id
execute immediate ' drop table :tab' using tab_prefix || tab_id
end;
ACCESS_INTO_NULL 未定义对象 CASE_NOT_FOUND CASE 中若未包含相应的 WHEN ,并且没有设置 ELSE 时 COLLECTION_IS_NULL 集合元素未初始化 CURSER_ALREADY_OPEN 游标已经打开 DUP_VAL_ON_INDEX 唯一索引对应的列上有重复的值 INVALID_CURSOR 在不合法的游标上进行操作 INVALID_NUMBER 内嵌的 SQL 语句不能将字符转换为数字 NO_DATA_FOUND 使用 select into 未返回行,或应用索引表未初始化的元素时 TOO_MANY_ROWS 执行 select into 时,结果集超过一行 ZERO_DIVIDE 除数为 0 SUBSCRIPT_BEYOND_COUNT 元素下标超过嵌套表或 VARRAY 的最大值 SUBSCRIPT_OUTSIDE_LIMIT 使用嵌套表或 VARRAY 时,将下标指定为负数 VALUE_ERROR 赋值时,变量长度不足以容纳实际数据 LOGIN_DENIED PL/SQL 应用程序连接到数据库时,提供了不正确的用户名或密码 NOT_LOGGED_ON PL/SQL 应用程序在没有连接数据库的情况下访问数据 PROGRAM_ERROR PL/SQL 内部问题,可能需要重装数据字典& pl./SQL 系统包 ROWTYPE_MISMATCH 宿主游标变量与 PL/SQL 游标变量的返回类型不兼容 SELF_IS_NULL 使用对象类型时,在 null 对象上调用对象方法 STORAGE_ERROR 运行 PL/SQL 时,超出内存空间 SYS_INVALID_ID 无效的 ROWID 字符串 TIMEOUT_ON_RESOURCE 在等待资源时超时用户自定义异常
DECLARE my_exception EXCEPTION
CREATE OR REPLACE PROCEDURE exception_init_test_0()
IS
declare
aaa exception
bbb exception
PRAGMA EXCEPTION_INIT(aaa,-20002)
PRAGMA EXCEPTION_INIT(bbb,-20002)
PRAGMA EXCEPTION_INIT(aaa,-1476)
PRAGMA EXCEPTION_INIT(bbb,-1476)
BEGIN
raise aaa
EXCEPTION
WHEN aaa then
put_line("Caught exception aaa, error code = " || sqlcode() || " error message is: " || sqlerrm())
END
;
输出结果为:
Caught exception aaa, error code = -1476 error message is: ZERO_DIVIDE
DECLARE
inner EXCEPTION
outer EXCEPTION
BEGIN
BEGIN
RAISE inner
EXCEPTION
WHEN inner THEN
raise outer
END
EXCEPTION
WHEN OTHERS THEN
select * from t1 where id = 10
END
DECLARE
var INT
inner EXCEPTION
outer EXCEPTION
BEGIN
var := 3
IF var > 2 THEN
BEGIN
raise inner
EXCEPTION
WHEN outer then
raise outer
END
END IF
EXCEPTION
WHEN inner THEN
select from t1 where id = 10
WHEN outer THEN
select from t1 where id = 10
END;
create or replace package pkg is --中文注释 包头
pv int := 0 --全局变量
type pvt is pv%type --包内类型
procedure pf_increase(i int) --包内函数
end;
create or replace package body pkg is -- 包体
/中文注释/
declare
pbv int := 1
function pbf_increase() return int
is
begin
pbv := pbv + 1
put_line('pbf_increase: pbv = ' || pbv)
return pbv
end
procedure pf_increase()
is
begin
pv := pv + pbf_increase()
put_line('pf_increase: pv = ' || pv)
end
begin
pv := 1
pbv := 2
pbf_increase()
pf_increase()
end;
declare
v1 pkg.pvt := 10 --直接使用包类型
v2 pkg.pv%type := 11
begin
dbms_output.put_line('pkg.pv = ' || pkg.pv)
pkg.pv := v1
dbms_output.put_line('pkg.pv = ' || pkg.pv)
pkg.pv := v2
dbms_output.put_line('pkg.pv = ' || pkg.pv)
end;
输出结果为:
pbf_increase: pbv = 3
pbf_increase: pbv = 4
pf_increase: pv = 5
pkg.pv = 5
pkg.pv = 10
pkg.pv = 11
CREATE OR REPLACE PROCEDURE exception_init_test_1()
IS
declare
aaa exception
bbb exception
PRAGMA EXCEPTION_INIT(aaa,-20002)
PRAGMA EXCEPTION_INIT(bbb,-20002)
BEGIN
raise aaa
EXCEPTION
WHEN bbb then
put_line("Caught exception bbb, error code = " || sqlcode() || " error message is: " || sqlerrm())
END
;
BEGIN
exception_init_test_1()
put_line("call finishes")
END;
输出结果:
Caught exception bbb, error code = -20002 error message is: USER_DEFINED
CREATE OR REPLACE PROCEDURE raise_application_error_test ()
IS
declare
aaa exception
PRAGMA EXCEPTION_INIT(aaa,-20001)
BEGIN
RAISE_APPLICATION_ERROR(-20001, "This is an error!")
EXCEPTION
WHEN aaa then
put_line("Caught an exception error code = " || sqlcode() || " error message is: " || sqlerrm())
END
;
BEGIN
raise_application_error_test()
put_line("call finishes")
END;
输出结果:
Caught an exception error code = -20001 error message is: This is an error!
call finishes
create or replace function outer_outer_func() return int is
owner string
name string
lineno int
ctype string
begin
put_line('Outer outer func')
owa_util.who_called_me(owner, name, lineno, ctype)
dbms_output.put_line('Owner: ' || owner)
dbms_output.put_line('Name: ' || name)
dbms_output.put_line('Lineno: ' || lineno)
dbms_output.put_line('Type: ' || ctype)
dbms_output.put_line('')
end;
begin
outer_outer_proc()
end;