Oracle中的动态SQL

来源:互联网 发布:安卓一键免流软件 编辑:程序博客网 时间:2024/06/06 08:36
  内容摘要:PL/SQL开发过程中,使用SQLPL/SQL可以实现大部份的需求,但是在某些特殊的情况下,在PL/SQL中使用准的SQL句或DML句不能实现自己的需求,比如需要动态建表或某个不确定的操作需要动态执行。就需要使用动态SQL实现。本文通几个例来详细动态SQL的使用。  

  本文适宜者范Oracle,中

  系统环境:

   OSwindows 2000 Professional (英文版)

   Oracle8.1.7.1.0

  正文:

  一般的PL/SQL程序设计中,在DML和事控制的句中可以直接使用SQL,但是DDL句及系控制句却不能在PL/SQL中直接使用,要想实现PL/SQL中使用DDL句及系控制句,可以通使用动态SQL实现

  首先我们应该了解什动态SQL,在Oracle数据库开发PL/SQL中我使用的SQL:静SQL句和动态SQL句。所SQL指在PL/SQL中使用的SQL句在编译时是明确的,行的是确定象。而动态SQL是指在PL/SQL块编译时SQL句是不确定的,如根据用户输入的参数的不同而行不同的操作。编译程序对动态语句部分不理,只是在程序运行时动态句、对语法分析并该语句。

  Oracle动态SQL可以通本地动态SQL行,也可以通DBMS_SQL包来行。下面就情况分别进明:

  一、本地动态SQL

  本地动态SQL是使用EXECUTE IMMEDIATE句来实现的。

  1、本地动态SQLDDL句:

  需求:根据用户输入的表名及字段名等参数动态建表。

create or replace procedure proc_test
(
table_name in varchar2, --表名
field1 in varchar2, --字段名
datatype1 in varchar2, --字段
field2 in varchar2, --字段名
datatype2 in varchar2 --字段
as 
str_sql varchar2(500);
begin
 
str_sql:=’create table ’||table_name||’(’||field1||’ ’||datatype1||’,’||field2||’ ’||datatype2||’)’;
execute
 immediate str_sql; --动态执DDL
exception
 
when
 others then 
null
;
end
 ;
  以上是编译的存储过程代。下面行存储过动态建表。

SQLexecute proc_test(’dinya_test’,’id’,’number(8) not null’,’name’,’varchar2(100)’);

PL/SQL procedure successfully completed

SQL
desc dinya_test;
Name
 Type Nullable Default Comments 
---- ------------- -------- ------- -------- 
ID
 NUMBER(8)

NAME
 VARCHAR2(100) Y

SQL
>
  到里,就实现了我的需求,使用本地动态SQL根据用户输入的表名及字段名、字段型等参数来实现动态执DDL句。

  2、本地动态SQLDML句。

  需求:将用户输入的插入到上例中建好的dinya_test表中。

create or replace procedure proc_insert
(
id
 in number, --入序号
name
 in varchar2 --入姓名
as 
str_sql varchar2(500);
begin
 
str_sql:=’insert into dinya_test values(:1,:2)’;
execute
 immediate str_sql using id,name; --动态执行插入操作
exception
 
when
 others then 
null
;
end
 ;
  行存储过程,插入数据到测试表中。

SQLexecute proc_insert(1,’dinya’);
PL/SQL procedure successfully completed
SQL
select * from dinya_test;
ID
 NAME
1 dinya
  在上例中,本地动态SQLDML使用了using子句,按序将入的值绑定到量,如果需要出参数,可以在动态SQL候,使用RETURNING INTO 子句,如:

declare
p_id number:=1;
v_count number;
begin
 
v_string:=’select count(*) from table_name a where a.id=:id’;
execute
 immediate v_string into v_count using p_id; 
end
 ;
  更多的动态SQL于返回为输行参数模式的问题请读者自行做测试

  二、使用DBMS_SQL

  使用DBMS_SQL实现动态SQL步骤如下:A、先将要行的SQL句或一个放到一个字符串量中。B、使用DBMS_SQL包的parse程来分析字符串。C、使用DBMS_SQL包的bind_variable程来量。D、使用DBMS_SQL包的execute函数来句。

  1、使用DBMS_SQLDDL

  需求:使用DBMS_SQL包根据用户输入的表名、字段名及字段型建表。

create or replace procedure proc_dbms_sql
(
table_name in varchar2, --表名
field_name1 in varchar2, --字段名
datatype1 in varchar2, --字段
field_name2 in varchar2, --字段名
datatype2 in varchar2 --字段
)as
v_cursor number; --
v_string varchar2(200); --字符串
v_row number; --行数
begin
v_cursor:=dbms_sql.open_cursor; --为处理打
v_string:=’create table ’||table_name||’(’||field_name1||’ ’||datatype1||’,’||field_name2||’ ’||datatype2||’)’;
dbms_sql.parse(v_cursor,v_string,dbms_sql.native); --分析
v_row:=dbms_sql.execute(v_cursor); --
dbms_sql.close_cursor(v_cursor); --关闭
exception
when
 others then
dbms_sql.close_cursor(v_cursor); --关闭
raise
;
end
;
  以上编译后,建表构:

SQLexecute proc_dbms_sql(’dinya_test2’,’id’,’number(8) not null’,’name’,’varchar2(100)’);

PL/SQL procedure successfully completed

SQL
desc dinya_test2;
Name
 Type Nullable Default Comments 
---- ------------- -------- ------- -------- 
ID
 NUMBER(8) 
NAME
 VARCHAR2(100) Y 

SQL
>
  2、使用DBMS_SQLDML

  需求:使用DBMS_SQL包根据用户输入的更新表中相对应记录

  看表中已有记录

SQLselect * from dinya_test2;
ID
 NAME
1 Oracle
2 CSDN
3 ERP
SQL
>
  建存储过程,并编译

create or replace procedure proc_dbms_sql_update
(
id
 number,
name
 varchar2
)as
v_cursor number; --
v_string varchar2(200); --字符串
v_row number; --行数
begin
v_cursor:=dbms_sql.open_cursor; --为处理打
v_string:=’update dinya_test2 a set a.name=:p_name where a.id=:p_id’;
dbms_sql.parse(v_cursor,v_string,dbms_sql.native); --分析
dbms_sql.bind_variable(v_cursor,’:p_name’,name); --
dbms_sql.bind_variable(v_cursor,’:p_id’,id); --
v_row:=dbms_sql.execute(v_cursor);           --动态SQL
dbms_sql.close_cursor(v_cursor); --关闭
exception
when
 others then
dbms_sql.close_cursor(v_cursor); --关闭
raise
;
end
;
  程,根据用户输入的参数更新表中的数据:

SQLexecute proc_dbms_sql_update(2,’csdn_dinya’);

PL/SQL procedure successfully completed

SQL
select * from dinya_test2;
ID
 NAME
1 Oracle
2 csdn_dinya
3 ERP
SQL
>
  程后将第二条的name字段的数据更新csdn_dinya这样就完成了使用dbms_sql包来DML句的功能。

  使用DBMS_SQL中,如果要行的动态语句不是查询语句,使用DBMS_SQL.ExecuteDBMS_SQL.Variable_Value行,如果要动态语句是查询语句,要使用DBMS_SQL.define_column义输量,然后使用DBMS_SQL.Execute, DBMS_SQL.Fetch_Rows, DBMS_SQL.Column_ValueDBMS_SQL.Variable_Value查询并得到果。

  总结说明:

  在Oracle开发过程中,我可以使用动态SQLDDL句、DML句、事控制句及系控制句。但是需要注意的是,PL/SQL中使用动态SQLDDL句的候与的不同,在DDL中使用量是非法的(bind_variable(v_cursor,’:p_name’,name)),分析后不需要DBMS_SQL.Bind_Variable,直接将入的量加到字符串中即可。另外,DDL是在DBMS_SQL.PARSE时执行的,所以DBMS_SQL.EXECUTE也可以不用,即在上例中的v_row:=dbms_sql.execute(v_cursor)部分可以不要。
0 0
原创粉丝点击