MYSQL编程:PL/SQL开辟中静态SQL的利用办法
如IBM公司最近宣布让渠道合作伙伴分销其SaaS应用程序的新计划。微软认为MySQL学习教程是销售其云计算服务的重要组成部分。然而即使有这种趋势,DBaaS仍然不同于内部数据库,解决方案提供商必须认识到这一点;否则,他们不仅仅是丢失几个客户,而是要失去的更多。静态内容择要:在PL/SQL开辟过程当中,利用SQL,PL/SQL能够完成年夜部分的需求,可是在某些特别的情形下,在PL/SQL中利用尺度的SQL语句或DML语句不克不及完成本人的需求,好比必要静态建表或某个不断定的操纵必要静态实行。这就必要利用静态SQL来完成。本文经由过程几个实例来具体的解说静态SQL的利用。 本文合适读者局限:Oracle低级,中级体系情况:
OS:windows2000Professional(英文版)
Oracle:8.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包来实行。上面就这两种情形分离举行申明:
1、当地静态SQL
当地静态SQL是利用EXECUTEIMMEDIATE语句来完成的。
1、当地静态SQL实行DDL语句:
需求:依据用户输出的表名及字段名等参数静态建表。
createorreplaceprocedureproc_test
(
table_nameinvarchar2,--表名
field1invarchar2,--字段名
datatype1invarchar2,--字段范例
field2invarchar2,--字段名
datatype2invarchar2--字段范例
)as
str_sqlvarchar2(500);
begin
str_sql:=’createtable’||table_name||’(’||field1||’’||datatype1||’,’||field2||’’||datatype2||’)’;
executeimmediatestr_sql;--静态实行DDL语句
exception
whenothersthen
null;
end;
以上是编译经由过程的存储历程代码。上面实行存储历程静态建表。
SQL>executeproc_test(’dinya_test’,’id’,’number(8)notnull’,’name’,’varchar2(100)’);
PL/SQLproceduresuccessfullycompleted
SQL>descdinya_test;
NameTypeNullableDefaultComments
----------------------------------------
IDNUMBER(8)
NAMEVARCHAR2(100)Y
SQL>
到这里,就完成了我们的需求,利用当地静态SQL依据用户输出的表名及字段名、字段范例等参数来完成静态实行DDL语句。
2、当地静态SQL实行DML语句。
需求:将用户输出的值拔出到上例中建好的dinya_test表中。
createorreplaceprocedureproc_insert
(
idinnumber,--输出序号
nameinvarchar2--输出姓名
)as
str_sqlvarchar2(500);
begin
str_sql:=’insertintodinya_testvalues(:1,:2)’;
executeimmediatestr_sqlusingid,name;--静态实行拔出操纵
exception
whenothersthen
null;
end;
实行存储历程,拔出数据到测试表中。
SQL>executeproc_insert(1,’dinya’);
PL/SQLproceduresuccessfullycompleted
SQL>select*fromdinya_test;
IDNAME
1dinya
在上例中,当地静态SQL实行DML语句时利用了using子句,按按次将输出的值绑定到变量,假如必要输入参数,能够在实行静态SQL的时分,利用RETURNINGINTO子句,如:
declare
p_idnumber:=1;
v_countnumber;
begin
v_string:=’selectcount(*)fromtable_nameawherea.id=:id’;
executeimmediatev_stringintov_countusingp_id;
end;
更多的关于静态SQL中关于前往值及为输入输出绑定变量实行参数形式的成绩,请读者自行做测试。
2、利用DBMS_SQL包
利用DBMS_SQL包完成静态SQL的步骤以下:A、先将要实行的SQL语句或一个语句块放到一个字符串变量中。B、利用DBMS_SQL包的parse历程来剖析该字符串。C、利用DBMS_SQL包的bind_variable历程来绑定变量。D、利用DBMS_SQL包的execute函数来实行语句。
1、利用DBMS_SQL包实行DDL语句
需求:利用DBMS_SQL包依据用户输出的表名、字段名及字段范例建表。
createorreplaceprocedureproc_dbms_sql
(
table_nameinvarchar2,--表名
field_name1invarchar2,--字段名
datatype1invarchar2,--字段范例
field_name2invarchar2,--字段名
datatype2invarchar2--字段范例
)as
v_cursornumber;--界说光标
v_stringvarchar2(200);--界说字符串变量
v_rownumber;--行数
begin
v_cursor:=dbms_sql.open_cursor;--为处置翻开光标
v_string:=’createtable’||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
whenothersthen
dbms_sql.close_cursor(v_cursor);--封闭光标
raise;
end;
以上历程编译经由过程后,实行历程创立表布局:
SQL>executeproc_dbms_sql(’dinya_test2’,’id’,’number(8)notnull’,’name’,’varchar2(100)’);
PL/SQLproceduresuccessfullycompleted
SQL>descdinya_test2;
NameTypeNullableDefaultComments
----------------------------------------
IDNUMBER(8)
NAMEVARCHAR2(100)Y
SQL>
2、利用DBMS_SQL包实行DML语句
需求:利用DBMS_SQL包依据用户输出的值更新表中绝对应的纪录。
检察表中已有纪录:
SQL>select*fromdinya_test2;
IDNAME
1Oracle
2CSDN
3ERP
SQL>
建存储历程,并编译经由过程:
createorreplaceprocedureproc_dbms_sql_update
(
idnumber,
namevarchar2
)as
v_cursornumber;--界说光标
v_stringvarchar2(200);--字符串变量
v_rownumber;--行数
begin
v_cursor:=dbms_sql.open_cursor;--为处置翻开光标
v_string:=’updatedinya_test2aseta.name=:p_namewherea.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
whenothersthen
dbms_sql.close_cursor(v_cursor);--封闭光标
raise;
end;
实行历程,依据用户输出的参数更新表中的数据:
SQL>executeproc_dbms_sql_update(2,’csdn_dinya’);
PL/SQLproceduresuccessfullycompleted
SQL>select*fromdinya_test2;
IDNAME
1Oracle
2csdn_dinya
3ERP
SQL>
实行历程后将第二条的name字段的数据更新为新值csdn_dinya。如许就完成了利用dbms_sql包来实行DML语句的功效。
利用DBMS_SQL中,假如要实行的静态语句不是查询语句,利用DBMS_SQL.Execute或DBMS_SQL.Variable_Value来实行,假如要实行静态语句是查询语句,则要利用DBMS_SQL.define_column界说输入变量,然后利用DBMS_SQL.Execute,DBMS_SQL.Fetch_Rows,DBMS_SQL.Column_Value及DBMS_SQL.Variable_Value来实行查询并失掉了局。
总结申明:
<P> 在Oracle开辟过程当中,我们可使用静态SQL来实行DDL语句、DML语句、事件把持语句及体系把持语句。可是必要注重的是,PL/SQL块中利用静态SQL实行DDL语句的时分与其余分歧,在DDL中利用绑定变量长短法的(bind_variable(v_cursor,’:p_name’,name)),剖析后不必要实行DBMS_SQL.Bind_Variable,间接将输出的变量加到字符串中便可。别的,DDL是在挪用DBMS_SQL.PARSE时实行的,以是DBMS_SQL.EXECUTE也能够不必,即在上例中的v_row:=dbms_sql.executDBaaS并不意味着解决方案提供者要让自己失业。与其他系统一样,在实施DBaaS解决方案时,客户可能需要部署、迁移、支持、异地备份、系统集成和灾难恢复等方面的帮助。 如果,某一版本可以提供强大的并发响应,但是没有Oracle的相应版本稳定,或者价格较贵,那么,它就是不适合的。 一直以来个人感觉SQLServer的优化器要比Oracle的聪明。SQL2005的更是比2k聪明了不少。(有次作试验发现有的语句在200万级时还比50万级的相同语句要快show_text的一些提示没有找到解释。一直在奇怪。) 这是一个不错的新特性。虽然索引的附加字段没有索引键值效率高,但是相对映射到数据表中效率还是提高了很多。我做过试验,在我的实验环境中会比映射到表中提高30%左右的效率。 Mirror可以算是SQLServer的Dataguard了。但是能不能被大伙用起来就不知道了。 这一点很好的加强了profiler的功能。但是提到profiler提醒大家注意一点。windows2003要安装sp1补丁才能启动profiler。否则点击没有反应。 如果我们从集合论(关系代数)的角度来看,一张数据库的表就是一组数据元的关系,而每个SQL语句会改变一种或数种关系,从而产生出新的数据元的关系(即产生新的表)。 我是新手,正在学习数据库和操作系统,深感理论的泛广,唯有一步一步来,但是又感觉时间不够,收集了很多资料却总是没能认真的看完,希望有一个讨论板块,大家共同解决,共同分享,共同努力 一个百万级别的基本信息表A,一个百万级别的详细记录表B,A中有个身份证id,B中也有身份id;先要找出A中在B的详细记录。
页:
[1]