DBMS_SQL包¶
包DBMS_SQL对动态SQL查询功能提供一个与Oracle兼容的应用程序接口。
类型:
下面的表中列出了DBMS_SQL包中的扩展类型:
| 类型 | 描述 |
|---|---|
| NUMBER_TABLE | 元素为NUMBER类型的索引集合 |
| DATE_TABLE | 元素为DATE类型的索引集合 |
过程/函数:
下表展示了DBMS_SQL包的子程序。
| 子程序 | 描述 | 过程/函数 |
|---|---|---|
| OPEN_CURSOR | 打开一个游标 | 函数 |
| PARSE | 解析一条语句 | 过程 |
| EXECUTE | 执行一个游标 | 函数 |
| CLOSE_CURSOR | 关闭一个游标 | 过程 |
| FETCH_ROWS | 获取SELECT语句的一行结果 | 函数 |
| IS_OPEN | 给定游标是否打开,是返回TRUE | 函数 |
| DESCRIBE_COLUMNS | 描述打开和解析的游标的列 | 过程 |
| DEFINE_COLUMN | 在select列表中定义一个列 | 过程 |
| COLUMN_VALUE | 将一个列的值返回到变量中 | 过程 |
| BIND_VARIABLE | 将一个值绑定在一个变量上 | 过程 |
| LAST_ERROR_POSITION | 返回发生错误字符位置 | 过程 |
以下介绍了各种函数和过程的语法、参数和说明。
示例
--DBMS_SQL.NUMBER_TABLE示例
DECLARE
n DBMS_SQL.NUMBER_TABLE;
BEGIN
n(1) := 2; --按下标给集合中元素赋值,元素为NUMBER类型
n(2) := 3;
for i in 1 .. n.count loop
DBMS_OUTPUT.PUT_LINE(n(i));
end loop;
END;
/
--DBMS_SQL.DATE_TABLE示例
DECLARE
d DBMS_SQL.DATE_TABLE;
BEGIN
d(1) := to_date('2022.12.7'); --按下标给集合中元素赋值,元素为DATE类型
d(2) := to_date('2022.12.8');
for i in 1 .. d.count loop
DBMS_OUTPUT.PUT_LINE(d(i));
end loop;
END;
/
--子程序示例
DROP TABLE phone_infor;--清理环境
create table phone_infor(phone_name VARCHAR(20),producer VARCHAR(20),price number);
CREATE OR REPLACE PROCEDURE p_1 IS
v_cursor INTEGER;
sqlstring VARCHAR2(200);
v_phone_name VARCHAR(20);
v_producer VARCHAR(20);
v_price INTEGER :=500;
v_count INT;
BEGIN
sqlstring :='INSERT INTO phone_infor values(:a,:b,:c)';
v_phone_name := 'TEST';
v_producer := 'sony';
v_price := 999;
v_cursor :=dbms_sql.open_cursor;
dbms_sql.parse(v_cursor ,sqlstring,dbms_sql.native);
dbms_sql.bind_variable(v_cursor,'a',v_phone_name,4);
dbms_sql.bind_variable(v_cursor,'b',v_producer);
dbms_sql.bind_variable(v_cursor,'c',v_price);
v_count := dbms_sql.EXECUTE(v_cursor);
dbms_sql.close_cursor(v_cursor);
dbms_output.put_line(' INSERT ' || to_char(v_count) ||' row ');
COMMIT;
END;
/
exec p_1;
select * from phone_infor;
PHONE_NAME(varchar) |PRODUCER(varchar) |PRICE(numeric) |
--------------------------------------------------------------------
TEST |sony |999 |
总数目:1
drop table phone_infor;
drop procedure p_1 cascade;
drop procedure equal_int cascade;
create or replace procedure equal_int(a integer, b integer) is
error_sql varchar(1000);
begin
if a <> b then
error_sql := 'error: '||a||' != '||b;
RAISE_APPLICATION_ERROR(-20010, error_sql);
end if;
end;
/
drop procedure equal_var cascade;
create or replace procedure equal_var(a varchar2, b varchar2) is
error_sql varchar(2000);
v1 varchar2(1000) := trim(a);
v2 varchar2(1000) := trim(b);
begin
if v1 <> v2 then
error_sql := 'error: '||a||' != '||b;
RAISE_APPLICATION_ERROR(-20010, error_sql);
end if;
end;
/
drop table test cascade;
create table test(c1 int, c2 int2, c3 int8, c4 number, c5 decimal, c6 float, c7 varchar(10));
insert into test values(1, 2, 3, 4, 5, 6.0, 'var7');
CREATE OR REPLACE PROCEDURE p_2 IS
sql_id INTEGER;
sql_stmt VARCHAR2(600);
v1 INT := -1;
v2 INT2 := -1;
v3 INT8 := -1;
v4 NUMBER := -1;
v5 DECIMAL := -1;
v6 FLOAT := -1;
v7 VARCHAR(20) := '';
BEGIN
sql_id := DBMS_SQL.OPEN_CURSOR();--打开游标
sql_stmt := 'select * from test';
DBMS_SQL.PARSE(sql_id, sql_stmt, DBMS_SQL.NATIVE); --解析语句
DBMS_SQL.DEFINE_COLUMN(sql_id, 1, v1); ----定义列
DBMS_SQL.DEFINE_COLUMN(sql_id, 2, v2);
DBMS_SQL.DEFINE_COLUMN(sql_id, 3, v3);
DBMS_SQL.DEFINE_COLUMN(sql_id, 4, v4);
DBMS_SQL.DEFINE_COLUMN(sql_id, 5, v5);
DBMS_SQL.DEFINE_COLUMN(sql_id, 6, v6);
DBMS_SQL.DEFINE_COLUMN(sql_id, 7, v7, 20);
equal_int(DBMS_SQL.EXECUTE(sql_id), 0); --执行sql语句
equal_int(DBMS_SQL.FETCH_ROWS(sql_id), 1);--fetch_rows在结果集中移动游标,如果未抵达末尾,返回1。
DBMS_SQL.COLUMN_VALUE(sql_id, 1, v1); --将当前行的查询结果写入上面定义的列中。
DBMS_SQL.COLUMN_VALUE(sql_id, 2, v2);
DBMS_SQL.COLUMN_VALUE(sql_id, 3, v3);
DBMS_SQL.COLUMN_VALUE(sql_id, 4, v4);
DBMS_SQL.COLUMN_VALUE(sql_id, 5, v5);
DBMS_SQL.COLUMN_VALUE(sql_id, 6, v6);
DBMS_SQL.COLUMN_VALUE(sql_id, 7, v7);
equal_int(v1, 1);
equal_int(v2, 2);
equal_int(v3, 3);
equal_int(v4, 4);
equal_int(v5, 5);
equal_int(v6, 6);
equal_var(v7, 'var7');
DBMS_SQL.CLOSE_CURSOR(sql_id);--关闭游标
END;
/
exec p_2;
drop table test cascade;
drop procedure equal_int cascade;
drop procedure equal_var cascade;
drop procedure p_2 cascade;