#DBMS_SQL

DBMS_SQL包提供了一组内置接口,用于执行动态SQL,包括DDL和DML。

# OPEN_CURSOR

DBMS_SQL.OPEN_CURSOR (
   security_level                 IN     INTEGER    DEFAULT 1,
   treat_as_client_for_results    IN     BOOLEAN    DEFAULT FALSE) 
  RETURN INTEGER;

OPEN_CURSOR用于打开一个新游标,返回游标的ID值,返回值为INTEGER类型。

参数 描述
security_level 安全级别,INTEGER类型。默认值为1,其他合法值为语法兼容。
treat_as_client_for_results 语法兼容。

说明:

  • 打开的游标为session级别资源,主动关闭或session断连时释放游标资源。
  • 游标可以重复执行SQL语句或解析新SQL语句,无需关闭再重新打开游标。
  • 暂只支持安全级别1,在绑定变量和执行阶段检查用户是否与解析阶段相同。

示例

DECLARE
  C INTEGER;
BEGIN
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

# CLOSE_CURSOR

DBMS_SQL.CLOSE_CURSOR (
   c    IN OUT INTEGER);

CLOSE_CURSOR用于关闭一个给定游标,释放相应的游标资源。

参数 描述
c 需要释放的游标ID,INTEGER类型。
执行成功后可作为输出参数,并将被自动赋值为NULL。

示例

DECLARE
  C INTEGER;
BEGIN
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

# PARSE

DBMS_SQL.PARSE (
   c                           IN   INTEGER,
   statement                   IN   VARCHAR2,
   language_flag               IN   INTEGER[
 [,edition                     IN   VARCHAR2 DEFAULT NULL],
   apply_crossedition_trigger  IN   VARCHAR2 DEFAULT NULL,
   fire_apply_trigger          IN   BOOLEAN DEFAULT TRUE]
 [,schema                      IN   VARCHAR2 DEFAULT NULL]
 [,container                   IN   VARCHAR2)];

或:

DBMS_SQL.PARSE (
   c                           IN   INTEGER,
   statement                   IN   CLOB,
   language_flag               IN   INTEGER[
 [,edition                     IN   VARCHAR2 DEFAULT NULL],
   apply_crossedition_trigger  IN   VARCHAR2 DEFAULT NULL,
   fire_apply_trigger          IN   BOOLEAN DEFAULT TRUE]
 [,schema                      IN   VARCHAR2 DEFAULT NULL]
 [,container                   IN   VARCHAR2)];  

PARSE使用给定的游标,解析给定的SQL语句。

参数 描述
c 使用游标的ID,INTEGER类型。
statement 语法解析的SQL语句,VARCHAR类型或CLOB类型。
若SQL语句的长度大于32K,则需使用CLOB类型。
language_flag 合法值范围0-6,常用值为常量DBMS_SQL.NATIVE。语法兼容。
edition 语法兼容。
apply_crossedition_trigger 语法兼容。
fire_apply_trigger 语法兼容。
schema 指定解析非限定对象名称的SCHEMA,如果为NULL,则为当前的SCHEMA。
container 语法兼容。

说明:

  • SQL语句最大长度不能超过2M。
  • DDL语句会在PARSE过程中立即执行。

示例

DECLARE
  C INTEGER;
  V_SQL VARCHAR(32000);
BEGIN
  V_SQL := 'SELECT * FROM dual';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

# BIND_VARIABLE

DBMS_SQL.BIND_VARIABLE (
   c              IN INTEGER,
   name           IN VARCHAR2,
   value          IN <datatype>);

或:

DBMS_SQL.BIND_VARIABLE (
   c              IN INTEGER,
   name           IN VARCHAR2,
   value          IN VARCHAR2 [,out_value_size IN INTEGER]);

BIND_VARIABLE根据语句中绑定变量名称将值绑定到绑定变量内。

参数 描述
c 使用游标的ID,INTEGER类型。
name 绑定参数名称,VARCHAR类型。需要与语句内的绑定变量名称匹配。
value 绑定到绑定变量的值,可为SQL语句支持的任一类型。
out_value_size 指定VARCHAR类型的出参值大小,INTEGER类型。

说明:

  • name参数中的前导冒号可以省略。
  • 如果指定了out_value_size,则视作value为VARCHAR类型。

示例

INSERT INTO department VALUES('111', '研发部');

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
BEGIN
  V_SQL := 'SELECT * FROM department WHERE department_name = :B1';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.BIND_VARIABLE(C, ':B1', '研发部');
  R := DBMS_SQL.EXECUTE(C);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/


DELETE FROM department WHERE deparment_no='111';

# BIND_VARIABLE_RAW

DBMS_SQL.BIND_VARIABLE_RAW (
   c              IN INTEGER,
   name           IN VARCHAR2,
   value          IN RAW [,out_value_size IN INTEGER]);

BIND_VARIABLE_RAW用于绑定RAW类型值的绑定变量。

参数 描述
c 使用游标的ID,INTEGER类型。
name 绑定参数名称,VARCHAR类型。需要与语句内的绑定变量名称匹配。
value 绑定到绑定变量的值,RAW类型。
out_value_size 指定RAW类型的出参值大小,INTEGER类型。

示例

CREATE TABLE bind_raw(c1 INT, c2 RAW(100));
INSERT INTO bind_raw VALUES(1, '1');
COMMIT;

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
BEGIN
  V_SQL := 'SELECT * FROM bind_raw WHERE C2 = :B1';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.BIND_VARIABLE_RAW(C, ':B1', '1');
  R := DBMS_SQL.EXECUTE(C);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/


DROP TABLE bind_raw;

# BIND_VARIABLE_CHAR

DBMS_SQL.BIND_VARIABLE_CHAR (
   c              IN INTEGER,
   name           IN VARCHAR2,
   value          IN CHAR [,out_value_size IN INTEGER]);

BIND_VARIABLE_CHAR用于绑定CHAR类型值的绑定变量。

参数 描述
c 使用游标的ID,INTEGER类型。
name 绑定参数名称,VARCHAR类型。需要与语句内的绑定变量名称匹配。
value 绑定到绑定变量的值,CHAR类型。
out_value_size 指定RAW类型的出参值大小,INTEGER类型。

示例

CREATE TABLE bind_char(c1 INT, c2 CHAR(100));
INSERT INTO bind_char VALUES(1, '1');
COMMIT;

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
BEGIN
  V_SQL := 'SELECT * FROM bind_char WHERE C2 = :B1';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.BIND_VARIABLE_CHAR(C, ':B1', '1');
  R := DBMS_SQL.EXECUTE(C);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/


DROP TABLE bind_char;

# BIND_ARRAY

DBMS_SQL.BIND_ARRAY ( 
   c                   IN INTEGER, 
   name                IN VARCHAR2, 
   <table_variable>    IN <datatype> 
 [,index1              IN INTEGER, 
   index2              IN INTEGER)] ); 

BIND_ARRAY用于批量绑定变量,进行批量执行DML语句。

参数 描述
c 使用游标的ID,INTEGER类型。
name 绑定参数名称,VARCHAR类型。需要与语句内的绑定变量名称匹配。
table_variable 绑定到绑定变量的值,类型需要是DBMS_SQL中定义的公共嵌套表类型。
index1 绑定的table成员的下限索引。
index2 绑定的table成员的上限索引。

说明:

  • index1和index2中间可以是不连续的。
  • BIND_ARRAY和DEFINE_ARRAY不能同时使用。

示例

DECLARE
  V_INT_TABLE DBMS_SQL.NUMBER_TABLE := DBMS_SQL.NUMBER_TABLE(1=>1, 2=>2);
  V_VARCHAR_TABLE DBMS_SQL.VARCHAR2_TABLE := DBMS_SQL.VARCHAR2_TABLE(1=>'运营部', 2=>'质检部');
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
BEGIN
  V_SQL := 'INSERT INTO department VALUES(:1, :2)';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.BIND_ARRAY(C, ':1', V_INT_TABLE);
  DBMS_SQL.BIND_ARRAY(C, ':2', V_VARCHAR_TABLE);
  R := DBMS_SQL.EXECUTE(C);
  COMMIT;
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/


SELECT deparment_no,department_name FROM department;
DEPARMENT_NO DEPARTMENT_NAME
------------ ---------------------
000          不分部门
010          销售部
008          采购部
002          财务部
1            运营部
2            质检部


DELETE FROM department WHERE deparment_no IN ('1','2');

# DEFINE_COLUMN

DBMS_SQL.DEFINE_COLUMN (
   c              IN INTEGER,
   position       IN INTEGER,
   column         IN <datatype>);

或:

DBMS_SQL.DEFINE_COLUMN (
   c              IN INTEGER,
   position       IN INTEGER,
   column         IN VARCHAR2,
   column_size    IN INTEGER);

DEFINE_COLUMN用于定义给定游标的投影列的位置。

仅当游标中为QUERY语句时,可使用该子过程。

参数 描述
c 使用游标的ID,INTEGER类型。
position 定义列的相对位置,INTEGER类型,下标从1开始。
column 定义列的值,由值的类型确定所定义列的类型。
column_size VARCHAR类型列的列值的期望大小。

说明:

  • column为CHAR或NCHAR类型时,必须指定column_size。
  • 如果指定了column_size,则视作column为VARCHAR类型。

示例

SELECT deparment_no,department_name FROM department;
DEPARMENT_NO DEPARTMENT_NAME
------------ ---------------------
000          不分部门
010          销售部
008          采购部
002          财务部


DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_INT INT;
  V_VARCHAR VARCHAR(100);
BEGIN
  V_SQL := 'SELECT * FROM department';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_COLUMN(C, 1, V_INT);
  DBMS_SQL.DEFINE_COLUMN(C, 2, V_VARCHAR, 100);
  R := DBMS_SQL.EXECUTE(C);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE(C, 1, V_INT);
  DBMS_SQL.COLUMN_VALUE(C, 2, V_VARCHAR);
  DBMS_OUTPUT.PUT_LINE(V_INT || V_VARCHAR);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
0不分部门

# DEFINE_COLUMN_RAW

DBMS_SQL.DEFINE_COLUMN_RAW (
   c              IN INTEGER,
   position       IN INTEGER,
   column         IN RAW,
   column_size    IN INTEGER);

DEFINE_COLUMN_RAW用于定义给定游标的投影列的位置,列的值为RAW类型。

仅当游标中为QUERY语句时,可使用该子过程。

参数 描述
c 使用游标的ID,INTEGER类型。
position 定义列的相对位置,INTEGER类型,下标从1开始。
column 定义列的值,RAW类型。
column_size RAW类型列的列值的期望大小。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_RAW RAW(10);
BEGIN
  V_SQL := 'SELECT ''6364'' FROM dual';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_COLUMN_RAW(C, 1, V_RAW, 10);
  R := DBMS_SQL.EXECUTE(C);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE_RAW(C, 1, V_RAW);
  DBMS_OUTPUT.PUT_LINE(V_RAW);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
6364

# DEFINE_COLUMN_CHAR

DBMS_SQL.DEFINE_COLUMN_CHAR (
   c              IN INTEGER,
   position       IN INTEGER,
   column         IN CHAR,
   column_size    IN INTEGER);

DEFINE_COLUMN_CHAR用于定义给定游标的投影列的位置,列的值为CHAR类型。

仅当游标中为QUERY语句时,可使用该子过程。

参数 描述
c 使用游标的ID,INTEGER类型。
position 定义列的相对位置,INTEGER类型,下标从1开始。
column 定义列的值,CHAR类型。
column_size CHAR类型列的列值的期望大小。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_CHAR CHAR(10);
BEGIN
  V_SQL := 'SELECT ''abc'' FROM dual';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_COLUMN_CHAR(C, 1, V_CHAR, 10);
  R := DBMS_SQL.EXECUTE(C);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE_CHAR(C, 1, V_CHAR);
  DBMS_OUTPUT.PUT_LINE(V_CHAR);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
abc       

# DEFINE_ARRAY

DBMS_SQL.DEFINE_ARRAY (
   c           IN INTEGER, 
   position    IN INTEGER,
   <table_variable>    IN <datatype> 
   cnt         IN INTEGER, 
   lower_bnd   IN INTEGER);

DEFINE_ARRAY用于定义需要FETCH的列,通过此过程从SELECT语句中FETCH多行结果集到嵌套表变量。

仅当游标中为QUERY语句时,可使用该子过程。

参数 描述
c 使用游标的ID,INTEGER类型。
position 定义列的相对位置,INTEGER类型,下标从1开始。
table_variable 定义为DBMS_SQL内置嵌套表类型的变量,数据类型为DBMS_SQL中定义的嵌套表类型。
cnt 需要获取的结果集行数。
lower_bnd 结果集复制到嵌套表变量的下限索引位置。

说明:

  • 在执行FETCH_ROWS时将结果集发送到缓冲区,更新当前索引位置,执行COLUMN_VALUE时将缓冲区值赋值到变量,更新下限索引位置。
  • DEFINE_ARRAY和BIND_ARRAY不能同时使用。

示例

SELECT deparment_no,department_name FROM department;
DEPARMENT_NO DEPARTMENT_NAME
------------ ---------------------
000          不分部门
010          销售部
008          采购部
002          财务部


DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_NUMBER_TABLE DBMS_SQL.NUMBER_TABLE;
  V_VARCHAR_TABLE DBMS_SQL.VARCHAR2_TABLE;
BEGIN
  V_SQL := 'SELECT * FROM department';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_ARRAY(C, 1, V_NUMBER_TABLE, 2, 1);
  DBMS_SQL.DEFINE_ARRAY(C, 2, V_VARCHAR_TABLE, 2, 1);
  R := DBMS_SQL.EXECUTE(C);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE(C, 1, V_NUMBER_TABLE);
  DBMS_SQL.COLUMN_VALUE(C, 2, V_VARCHAR_TABLE);
  FOR I IN V_NUMBER_TABLE.FIRST .. V_NUMBER_TABLE.LAST LOOP
    DBMS_OUTPUT.PUT_LINE(i || ': ' || V_NUMBER_TABLE(i) || ', ' ||V_VARCHAR_TABLE(i));
  END LOOP;
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/
--result
1: 0, 不分部门
2: 10, 销售部

# EXECUTE

DBMS_SQL.EXECUTE (
   c   IN INTEGER)
  RETURN INTEGER;

EXECUTE用于执行游标语句,返回已处理的行数,INTEGER类型。只有游标语句为INSERT、UPDATE和DELETE语句的返回值才有效。

参数 描述
c 使用游标的ID,INTEGER类型。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
BEGIN
  V_SQL := 'SELECT * FROM dual';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  R := DBMS_SQL.EXECUTE(C);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

# FETCH_ROWS

DBMS_SQL.FETCH_ROWS (
   c              IN INTEGER)
  RETURN INTEGER;

FETCH_ROWS用于获取结果集,返回实际获取的行数,INTEGER类型。对于DEFINE_ARRAY的游标,一次将获取多行结果集。

仅当游标中为QUERY语句时,可使用该子过程。

参数 描述
c 使用游标的ID,INTEGER类型。

示例

SELECT deparment_no,department_name FROM department;
DEPARMENT_NO DEPARTMENT_NAME
------------ ---------------------
000          不分部门
010          销售部
008          采购部
002          财务部


DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_INT INT;
  V_VARCHAR VARCHAR(100);
BEGIN
  V_SQL := 'SELECT * FROM department';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_COLUMN(C, 1, V_INT);
  DBMS_SQL.DEFINE_COLUMN(C, 2, V_VARCHAR, 100);
  R := DBMS_SQL.EXECUTE(C);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE(C, 1, V_INT);
  DBMS_SQL.COLUMN_VALUE(C, 2, V_VARCHAR);
  DBMS_OUTPUT.PUT_LINE(V_INT || V_VARCHAR);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
0不分部门

# EXECUTE_AND_FETCH

DBMS_SQL.EXECUTE_AND_FETCH (
   c              IN INTEGER,
   exact          IN BOOLEAN DEFAULT FALSE)
  RETURN INTEGER;

EXECUTE_AND_FETCH执行给定的游标并获取结果集。返回实际获取的行数,INTEGER类型。

仅当游标中为QUERY语句时,可使用该子过程。

参数 描述
c 使用游标的ID,INTEGER类型。
exact 用于指定是否检查结果集行数。设置为TRUE时,检查返回的结果集是否为1行,否则报错。设置为FALSE则不检查返回的结果集行数。

示例

SELECT deparment_no,department_name FROM department;
DEPARMENT_NO DEPARTMENT_NAME
------------ ---------------------
000          不分部门
010          销售部
008          采购部
002          财务部


DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_INT INT;
  V_VARCHAR VARCHAR(100);
BEGIN
  V_SQL := 'SELECT * FROM department';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_COLUMN(C, 1, V_INT);
  DBMS_SQL.DEFINE_COLUMN(C, 2, V_VARCHAR, 100);
  R := DBMS_SQL.EXECUTE_AND_FETCH(C);
  DBMS_SQL.COLUMN_VALUE(C, 1, V_INT);
  DBMS_SQL.COLUMN_VALUE(C, 2, V_VARCHAR);
  DBMS_OUTPUT.PUT_LINE(V_INT || V_VARCHAR);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
0不分部门

# VARIABLE_VALUE

DBMS_SQL.VARIABLE_VALUE (
   c               IN  INTEGER,
   name            IN  VARCHAR2,
   value           OUT NOCOPY <datatype>);

VARIABLE_VALUE用于获取绑定变量的值。

参数 描述
c 使用游标的ID,INTEGER类型。
name 获取绑定变量值的名称,需要与语句中的绑定变量名称匹配,VARCHAR类型。
value 获取绑定变量值赋值的变量,可为SQL语句支持的任一类型。

说明:

  • name参数中的前导冒号可以省略。
  • VARIABLE_VALUE中value的数据类型需要与绑定阶段绑定变量的数据类型相匹配。

示例

INSERT INTO department VALUES('121', '客户服务部');

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_VARCHAR VARCHAR(100);
BEGIN
  V_SQL := 'SELECT * FROM department WHERE department_name = :B1';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.BIND_VARIABLE(C, ':B1', '客户服务部');
  R := DBMS_SQL.EXECUTE(C);
  DBMS_SQL.VARIABLE_VALUE(C, 'B1', V_VARCHAR);
  DBMS_OUTPUT.PUT_LINE(V_VARCHAR);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
客户服务部



DELETE FROM department WHERE deparment_no='121';

# VARIABLE_VALUE_RAW

DBMS_SQL.VARIABLE_VALUE_RAW (
   c               IN  INTEGER,
   name            IN  VARCHAR2,
   value           OUT RAW);

VARIABLE_VALUE_RAW用于获取RAW类型绑定变量的值。

参数 描述
c 使用游标的ID,INTEGER类型。
name 获取绑定变量值的名称,需要与语句中的绑定变量名称匹配,VARCHAR类型。
value 获取绑定变量值赋值的变量,RAW类型。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_RAW RAW(10) := '6364';
BEGIN
  V_SQL := 'begin :B1 := ''6566''; end;';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.BIND_VARIABLE_RAW(C, ':B1', V_RAW, 10);
  R := DBMS_SQL.EXECUTE(C);
  DBMS_SQL.VARIABLE_VALUE_RAW(C, 'B1', V_RAW);
  DBMS_OUTPUT.PUT_LINE(V_RAW);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
6566

# VARIABLE_VALUE_CHAR

DBMS_SQL.VARIABLE_VALUE_CHAR (
   c               IN  INTEGER,
   name            IN  VARCHAR2,
   value           OUT CHAR);

VARIABLE_VALUE_CHAR用于获取CHAR类型绑定变量的值。

参数 描述
c 使用游标的ID,INTEGER类型。
name 获取绑定变量值的名称,需要与语句中的绑定变量名称匹配,VARCHAR类型。
value 获取绑定变量值赋值的变量,CHAR类型。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_CHAR CHAR(10) := 'abc';
BEGIN
  V_SQL := 'begin :B1 := ''defg''; end;';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.BIND_VARIABLE_CHAR(C, ':B1', V_CHAR, 10);
  R := DBMS_SQL.EXECUTE(C);
  DBMS_SQL.VARIABLE_VALUE_CHAR(C, 'B1', V_CHAR);
  DBMS_OUTPUT.PUT_LINE(V_CHAR);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
defg      

# COLUMN_VALUE

DBMS_SQL.COLUMN_VALUE (
   c                 IN  INTEGER,
   position          IN  INTEGER,
   value             OUT <datatype> 
 [,column_error      OUT NUMBER] 
 [,actual_length     OUT INTEGER]);

COLUMN_VALUE返回游标获取的结果集中指定列的值并赋值给value。

仅当游标中为QUERY语句时,可使用该子过程。

参数 描述
c 使用游标的ID,INTEGER类型。
position 获取投影列的相对位置,INTEGER类型,下标从1开始。
value 获取结果集指定列的值并赋值给value,可为SQL语句支持的任一类型。
column_error 语法兼容。
actual_length 返回列截断前的实际长度。

示例

SELECT deparment_no,department_name FROM department;
DEPARMENT_NO DEPARTMENT_NAME
------------ ---------------------
000          不分部门
010          销售部
008          采购部
002          财务部


DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_INT INT;
  V_VARCHAR VARCHAR(100);
BEGIN
  V_SQL := 'SELECT * FROM department';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_COLUMN(C, 1, V_INT);
  DBMS_SQL.DEFINE_COLUMN(C, 2, V_VARCHAR, 100);
  R := DBMS_SQL.EXECUTE(C);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE(C, 1, V_INT);
  DBMS_SQL.COLUMN_VALUE(C, 2, V_VARCHAR);
  DBMS_OUTPUT.PUT_LINE(V_INT || V_VARCHAR);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
0不分部门

# COLUMN_VALUE_RAW

DBMS_SQL.COLUMN_VALUE_RAW (
   c                 IN  INTEGER,
   position          IN  INTEGER,
   value             OUT RAW 
 [,column_error      OUT NUMBER] 
 [,actual_length     OUT INTEGER]);

COLUMN_VALUE_RAW返回游标获取的结果集中指定列的RAW类型值并赋值给value。

仅当游标中为QUERY语句时,可使用该子过程。

参数 描述
c 使用游标的ID,INTEGER类型。
position 获取投影列的相对位置,INTEGER类型,下标从1开始。
value 获取结果集指定列的值并赋值给value,RAW类型。
column_error 语法兼容。
actual_length 返回列截断前的实际长度。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_RAW RAW(10);
BEGIN
  V_SQL := 'SELECT ''6364'' FROM dual';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_COLUMN_RAW(C, 1, V_RAW, 10);
  R := DBMS_SQL.EXECUTE(C);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE_RAW(C, 1, V_RAW);
  DBMS_OUTPUT.PUT_LINE(V_RAW);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
6364

# COLUMN_VALUE_CHAR

DBMS_SQL.COLUMN_VALUE_CHAR (
   c                 IN  INTEGER,
   position          IN  INTEGER,
   value             OUT CHAR 
 [,column_error      OUT NUMBER] 
 [,actual_length     OUT INTEGER]);

COLUMN_VALUE_CHAR返回游标获取的结果集中指定列的CHAR类型值并赋值给value。

仅当游标中为QUERY语句时,可使用该子过程。

参数 描述
c 使用游标的ID,INTEGER类型。
position 获取投影列的相对位置,INTEGER类型,下标从1开始。
value 获取结果集指定列的值并赋值给value,CHAR类型。
column_error 语法兼容。
actual_length 返回列截断前的实际长度。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_CHAR CHAR(10);
BEGIN
  V_SQL := 'SELECT ''abc'' FROM dual';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_COLUMN_CHAR(C, 1, V_CHAR, 10);
  R := DBMS_SQL.EXECUTE(C);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE_CHAR(C, 1, V_CHAR);
  DBMS_OUTPUT.PUT_LINE(V_CHAR);
  DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
abc       

# IS_OPEN

DBMS_SQL.IS_OPEN (
   c              IN INTEGER)
  RETURN BOOLEAN;

IS_OPEN用于判断游标是否处于打开状态。返回值为BOOLEAN类型,如果为打开状态,返回TRUE,如果入参为NULL,返回FALSE。

参数 描述
c 用于判断游标的ID,INTEGER类型。

示例

DECLARE
  C INTEGER;
  IS_OPEN BOOLEAN;
BEGIN
  C := DBMS_SQL.OPEN_CURSOR();
  IS_OPEN := DBMS_SQL.IS_OPEN(C);
  DBMS_OUTPUT.PUT_LINE(IS_OPEN);
  DBMS_SQL.CLOSE_CURSOR(C);
  IS_OPEN := DBMS_SQL.IS_OPEN(C);
  DBMS_OUTPUT.PUT_LINE(IS_OPEN);
END;
/

--result
true
false

# TO_REFCURSOR

DBMS_SQL.TO_REFCURSOR(
   cursor_number IN OUT INTEGER)
  RETURN SYS_REFCURSOR;

TO_REFCURSOR将一个打开、解析并执行过的游标转换为SYS_REFCURSOR,并返回转换后得到的SYS_REFCURSOR。

参数 描述
cursor_number 需要转换的游标ID,INTEGER类型。
执行成功后可作为输出参数,并将被自动赋值为NULL。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_INT INT;
  C_REF SYS_REFCURSOR;
BEGIN
  V_SQL := 'SELECT 1 FROM DUAL';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  R := DBMS_SQL.EXECUTE(C);
  C_REF := DBMS_SQL.TO_REFCURSOR(C);
  FETCH C_REF INTO V_INT;
  DBMS_OUTPUT.PUT_LINE(V_INT);
END;
/

--result
1

# TO_CURSOR_NUMBER

DBMS_SQL.TO_CURSOR_NUMBER(
   rc IN OUT SYS_REFCURSOR)
  RETURN INTEGER;

TO_CURSOR_NUMBER将一个打开的动态游标转换为由DBMS_SQL管理的游标,并返回转换后得到的游标ID。

转换后的DBMS_SQL游标处于已执行状态,不可重复执行。

参数 描述
rc 需要转换的动态游标,SYS_REFCURSOR类型。转换后该动态游标rc被设置为无效游标。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_INT INT;
  C_REF SYS_REFCURSOR;
BEGIN
  V_SQL := 'SELECT 1 FROM DUAL';
  OPEN C_REF FOR V_SQL;
  C := DBMS_SQL.TO_CURSOR_NUMBER(C_REF);
  DBMS_SQL.DEFINE_COLUMN(C, 1, V_INT);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE(C, 1, V_INT);
  DBMS_OUTPUT.PUT_LINE(V_INT);
END;
/

--result
1

# DESCRIBE_COLUMNS

DBMS_SQL.DESCRIBE_COLUMNS ( 
   c              IN  INTEGER, 
   col_cnt        OUT INTEGER, 
   desc_t         OUT DESC_TAB);

DESCRIBE_COLUMNS描述由DBMS_SQL打开并解析的游标的投影列。

参数 描述
c 使用游标的ID,INTEGER类型。
col_cnt 返回投影列的列数。
desc_t 返回每个投影列的描述信息。

示例

DECLARE
V_STR VARCHAR(100);
C INT;
COL_CNT INT;
REC_TABLE DBMS_SQL.DESC_TAB;
REC DBMS_SQL.DESC_REC;
R NUMBER;
COL_NUM NUMBER;
BEGIN
V_STR := 'SELECT deparment_no, department_name FROM department';
C := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(C, V_STR, 1);
DBMS_SQL.DESCRIBE_COLUMNS(C, COL_CNT, REC_TABLE);
COL_NUM := REC_TABLE.FIRST;
WHILE COL_NUM IS NOT NULL LOOP
	REC := REC_TABLE(COL_NUM);
	DBMS_OUTPUT.PUT_LINE('----COL: ' || COL_NUM || '----');
    DBMS_OUTPUT.PUT_LINE('COL_TYPE            =    ' || REC.COL_TYPE);
    DBMS_OUTPUT.PUT_LINE('COL_MAXLEN          =    ' || REC.COL_MAX_LEN);
    DBMS_OUTPUT.PUT_LINE('COL_NAME            =    ' || REC.COL_NAME);
    DBMS_OUTPUT.PUT_LINE('COL_NAME_LEN        =    ' || REC.COL_NAME_LEN);
    DBMS_OUTPUT.PUT_LINE('COL_SCHEMA_NAME     =    ' || REC.COL_SCHEMA_NAME);
    DBMS_OUTPUT.PUT_LINE('COL_SCHEMA_NAME_LEN =    ' || REC.COL_SCHEMA_NAME_LEN);
    DBMS_OUTPUT.PUT_LINE('COL_PRECISION       =    ' || REC.COL_PRECISION);
    DBMS_OUTPUT.PUT_LINE('COL_SCALE           =    ' || REC.COL_SCALE);
	  DBMS_OUTPUT.PUT_LINE('COL_CHARSETID       =    ' || REC.COL_CHARSETID);
	  DBMS_OUTPUT.PUT_LINE('COL_CHARSETFORM     =    ' || REC.COL_CHARSETFORM);
	  DBMS_OUTPUT.PUT_LINE('COL_NULL_OK         =    ' || REC.COL_NULL_OK);
	COL_NUM := REC_TABLE.NEXT(COL_NUM);
END LOOP;
DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result
----COL: 1----
COL_TYPE            =    24
COL_MAXLEN          =    3
COL_NAME            =    DEPARMENT_NO
COL_NAME_LEN        =    12
COL_SCHEMA_NAME     =
COL_SCHEMA_NAME_LEN =    0
COL_PRECISION       =    0
COL_SCALE           =    0
COL_CHARSETID       =    2
COL_CHARSETFORM     =
COL_NULL_OK         =    false
----COL: 2----
COL_TYPE            =    26
COL_MAXLEN          =    20
COL_NAME            =    DEPARTMENT_NAME
COL_NAME_LEN        =    15
COL_SCHEMA_NAME     =
COL_SCHEMA_NAME_LEN =    0
COL_PRECISION       =    0
COL_SCALE           =    0
COL_CHARSETID       =    2
COL_CHARSETFORM     =
COL_NULL_OK         =    true

# LAST_ERROR_POSITION

DBMS_SQL.LAST_ERROR_POSITION 
   RETURN INTEGER;

返回SQL语法的报错的字节偏移位置,偏移位置从0开始。

仅在DBMS_SQL.PARSE或DBMS_SQL.EXECUTE阶段报错且原有报错信息包含position信息时,才能获取到LAST_ERROR_POSITION。

示例

DECLARE
C1 INT;
V_SQL VARCHAR(100);
BEGIN
C1 := DBMS_SQL.OPEN_CURSOR();
V_SQL := 'SELECT X FROM DUAL';
DBMS_SQL.PARSE(C1, V_SQL, DBMS_SQL.NATIVE);
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(DBMS_SQL.LAST_ERROR_POSITION || ', ' || SQLERRM);
END;
/

--result
7, YAS-04243 invalid identifier "X"

# RETURN_RESULT

DBMS_SQL.RETURN_RESULT (
rc              IN OUT SYS_REFCURSOR,
to_client       IN BOOLEAN DEFAULT TRUE);

RETURN_RESULT为存储过程,用于执行指定SQL并返回结果集给客户端(例如接口程序),客户端获得结果集游标后,可以执行fetch语句查询结果。

当在yasql中执行本存储过程时,将直接输出结果集内容。

参数 描述
rc 动态游标。
to_client 是否返回结果集给客户端;默认为true,如果传入false并且是执行动态SQL时,结果集不返回给客户端。

Note

  • 当前只有查询结果集可以返回。
  • 执行返回结果集后,rc参数对应的游标不能再访问。
  • 客户端将缓存结果集的全部结果,但依赖客户端所在设备的内存大小。
  • 过程体执行过程中如果发生错误,客户端依然可以获取到错误点之前返回的结果集。

示例

CREATE OR REPLACE PROCEDURE return_rs_proc IS
cur1 SYS_REFCURSOR;
cur2 sys_refcursor;
BEGIN
  OPEN cur1 FOR SELECT area_no,area_name FROM area WHERE area_no='01';
  DBMS_SQL.RETURN_RESULT(cur1,false);
  OPEN cur2 FOR SELECT branch_no,branch_name FROM branches WHERE area_no='01';
  DBMS_SQL.RETURN_RESULT(cur2);
END;
/

-- 执行静态SQL
exec return_rs_proc;

ResultSet #1

AREA_NO AREA_NAME                                                     
------- ------------------------------------------------------------- 
01      华东                                                       


ResultSet #2

BRANCH_NO BRANCH_NAME                                                      
--------- ---------------------------------------------------------------- 
0101      上海                                                          
0102      南京                                                          
0103      福州                                                          
0104      厦门                                                          



-- 执行动态SQL,此时由于to_client为false,第一个结果集不会返回
BEGIN
  EXECUTE IMMEDIATE 'begin return_rs_proc; end;';
END;
/

ResultSet #1

BRANCH_NO BRANCH_NAME                                                      
--------- ---------------------------------------------------------------- 
0101      上海                                                          
0102      南京                                                          
0103      福州                                                          
0104      厦门                                                          

# 常量

常量 数据类型 说明
NATIVE INTEGER 1 指定程序连接的正常行为

# 异常

异常 描述
INCONSISTENT_TYPE 当COLUMN_VALUE子过程或VARIABLE_VALUE子过程给定的出参类型与先前定义的类型不匹配时,抛出此异常。

示例

DECLARE
  C INTEGER;
  R INTEGER;
  V_SQL VARCHAR(32000);
  V_INT INT;
  V_VARCHAR VARCHAR(100);
BEGIN
  V_SQL := 'SELECT 1 FROM DUAL';
  C := DBMS_SQL.OPEN_CURSOR();
  DBMS_SQL.PARSE(C, V_SQL, DBMS_SQL.NATIVE);
  DBMS_SQL.DEFINE_COLUMN(C, 1, V_INT);
  R := DBMS_SQL.EXECUTE(C);
  R := DBMS_SQL.FETCH_ROWS(C);
  DBMS_SQL.COLUMN_VALUE(C, 1, V_VARCHAR);
  EXCEPTION WHEN DBMS_SQL.INCONSISTENT_TYPE THEN
    DBMS_OUTPUT.PUT_LINE('type of out argument must match type of column or bind variable');
    DBMS_SQL.CLOSE_CURSOR(C);
END;
/

--result 
type of out argument must match type of column or bind variable

# DBMS_SQL DESC_REC Record Type

作为DESC_TAB嵌套表类型的成员类型,描述投影列信息。

TYPE desc_rec IS RECORD (
      col_type            BINARY_INTEGER := 0,
      col_max_len         BINARY_INTEGER := 0,
      col_name            VARCHAR2(64)   := '',
      col_name_len        BINARY_INTEGER := 0,
      col_schema_name     VARCHAR2(64)   := '',
      col_schema_name_len BINARY_INTEGER := 0,
      col_precision       BINARY_INTEGER := 0,
      col_scale           BINARY_INTEGER := 0,
      col_charsetid       BINARY_INTEGER := 0,
      col_charsetform     BINARY_INTEGER := 0,
      col_null_ok         BOOLEAN        := TRUE);
TYPE desc_tab IS TABLE OF desc_rec INDEX BY BINARY_INTEGER;
字段 类型 默认值 说明
col_type BINARY_INTEGER 0 列类型。
col_max_len BINARY_INTEGER 0 最大列长度。
col_name VARCHAR2(64) NULL 列名称。
col_name_len BINARY_INTEGER 0 列名称长度。
col_schema_name VARCHAR2(64) NULL 列schema名称。
col_schema_name_len BINARY_INTEGER 0 列schema名称长度。
col_precision BINARY_INTEGER 0 列precision。
col_scale BINARY_INTEGER 0 列scale。
col_charsetid BINARY_INTEGER 0 列字符串id。
col_charsetform BINARY_INTEGER 0 列字符集格式(保留字段)。
col_null_ok BOOLEAN TRUE 列是否可能为NULL,TRUE说明可能为NULL。

# DBMS_SQL DESC_TAB Table Type

用于保存describe_column获取列描述信息。

TYPE desc_tab IS TABLE OF desc_rec INDEX BY BINARY_INTEGER;

# DBMS_SQL TABLE Types For Scalar and LOB Collections

标量和LOB类型的嵌套表定义。

TYPE binary_double_table IS TABLE OF BINARY_DOUBLE  INDEX BY BINARY_INTEGER;
TYPE binary_float_table IS TABLE OF BINARY_FLOAT   INDEX BY BINARY_INTEGER;
TYPE blob_table     IS TABLE OF BLOB           INDEX BY BINARY_INTEGER;
TYPE clob_table     IS TABLE OF CLOB           INDEX BY BINARY_INTEGER;
TYPE date_table     IS TABLE OF DATE           INDEX BY BINARY_INTEGER;
TYPE interval_day_to_second_table IS TABLE OF INTERVAL DAY TO SECOND INDEX BY BINARY_INTEGER;
TYPE interval_year_to_month_table IS TABLE OF INTERVAL YEAR TO MONTH INDEX BY BINARY_INTEGER;
TYPE number_table   IS TABLE OF NUMBER         INDEX BY BINARY_INTEGER;
TYPE timestamp_table IS TABLE OF timestamp INDEX BY BINARY_INTEGER;
TYPE time_table IS TABLE OF TIME INDEX BY BINARY_INTEGER;
TYPE urowid_table IS TABLE OF UROWID INDEX BY BINARY_INTEGER;
TYPE varchar2_table IS TABLE OF VARCHAR2(32000) INDEX BY BINARY_INTEGER;