Oracle PL/SQL (12) - 动态SQL语句

1.静态SQL与动态SQL
Oracle编译PL/SQL程序块分为两个种:一种是,SQL语句在程序编译期间就已经确定,大多数的编译情况属于这种类型,如:静态SQL;另外一种是SQL语句只有在运行阶段才能建立,例如当查询条件为用户输入时,那么Oracle的SQL引擎就无法在编译期对该程序语句进行确定,只能在用户输入一定的查询条件后才能提交给SQL引擎进行处理。如:动态SQL。
本文主要就动态SQL的基础做总结。

2.使用EXECUTE IMMEDIATE语句处理相关语句:
动态SQL是一种”不确定”的SQL,那其执行就有其相应的特点。Oracle中提供了Execute immediate语句来执行动态SQL,语法如下:

Excute immediate 动态SQL语句 using 绑定参数列表 returning into 输出参数列表;
  1. USING 子句给动态语句传值
    例如:
declare 
  l_str1 varchar2(20) := 'hello'; 
  l_str2    varchar2(10) := 'world'; 
  begin 
  execute immediate 'insert into t_str values   (:1, :2, :3)' 
   using 50, l_str1 , l_str2 ; 
 commit;   -----一定要显示提交
end; 

4.INTO子句从动态语句检索值
例如:

declare 
 v_cnt    varchar2(20); 
begin 
  execute immediate 'select count(1) from emp'  into v_cnt    ; 
 dbms_output.put_line(v_cnt ); 
end; 

5.传递并检索值.INTO子句用在USING子句前
例如:

declare 
 v_empno    pls_integer := 20; 
 v_ename     varchar2(20); 
 v_esex     varchar2(20); 
begin 
  execute immediate 'select ename, esex from emp where empno = :1' 
   into v_ename,v_esex 
   using v_empno   ; 
end; 

6.输出参数returning into 子句用在USING子句后
例如:

create or replace procedure update_data(stuid varchar2, age number)
as
   strSQL varchar2(1000);
   strID varchar2(50);
   strName varchar2(50);
   strSex varchar2(50);
begin
   strSQL := 'update tb_student set age=:a where id=:b returning id, name, sex into :c, :d, :e';
   execute immediate strSQL using age, stuid returning into strID, strName, strSex;
   execute immediate 'commit'; -- 这样也是可以的
   dbms_output.put_line('ID:' || strID || ' ;Name:' || strName || ' ;Sex:' || strSex);
end;

在上面的代码中,:a、:b、:c、:d和:e都是占位符,占位符必须以冒号开始,名字无所谓。使用了占位符以后,就需要在execute immediate语句后面使用using将参数传递进去,参数将与占位符一一对应。但是有一点需要谨记,绑定参数不能是表名、列名、数据类型等,绑定参数只能是值、变量或者表达式。用DDL语句动态创建对象时,应该使用连接运算符||,最好不要使用绑定参数。
另外上述代码中还使用了一个returning into的关键语句,returning into语句的主要作用是:
delete操作:returning返回的是delete之前的结果
insert操作:returning返回的是insert之后的结果
update操作:returning语句是返回update之后的结果

7.通过游标实现多行查询的SELECT语句
例如:

declare
  type ref_cur is ref cursor;
  rc ref_cur;
  seriesrow t_Md_Vehicle_Series%rowtype;
  v_sql varchar2(500):='select * from t_Md_Vehicle_Series m where m.vehicle_make_id=:makeid';
  v_sql2 varchar2(500);
  type tb_model_type is table of t_md_vehicle_model%rowtype;
   model_array tb_model_type;
begin
 DBMS_OUTPUT.ENABLE(100000);

  open rc for v_sql using 'CN001';
  loop
     FETCH rc INTO seriesrow;
       EXIT WHEN rc%NOTFOUND;
       dbms_output.put_line('name:'||seriesrow.vehicle_series_name||'-------------->  id:'||seriesrow.vehicle_series_id);
       v_sql2:='select * from t_md_vehicle_model m where m.vehicle_series_id=:seriesid and m.valid_flag=1'; 
       execute immediate v_sql2 bulk collect into model_array using seriesrow.vehicle_series_id;
       for i in model_array.first .. model_array.last loop
       dbms_output.put_line('ID:' || model_array(i).vehicle_sub_model_id 
                           || '-------------->  Name:' || model_array(i).vehicle_sub_model_name  );
   end loop;
  end loop;
  CLOSE rc;
end;

输出结果:


image.png

上述语句中,用带有子句bulk collect into的execute immediate语句。采用bulk collect into可以将查询结果一次性地加载到集合中,可以在select into、fetch into、returning into语句中使用bulk collect into;但是需要特别注意的是,在使用bulk collect into时,所有的into变量都必须是集合类型。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342