zoukankan      html  css  js  c++  java
  • Oracle中动态SQL详解

    一:静态SQL与动态SQL
      Oracle编译PL/SQL程序块分为两种:一种为前期联编(early binding),即SQL语句在程序编译期间就已经确定,大多数的编译情况属于这种类型;另外一种是后期联编(late binding),即SQL语句只有在运行阶段才能建立,例如当查询条件为用户输入时,那么Oracle的SQL引擎就无法在编译期对该程序语句进行确定,只能在用户输入一定的查询条件后才能提交给SQL引擎进行处理。通常,静态SQL采用第一种编译方式,而动态SQL采用后一种编译方式。
      本文主要讨论动态SQL的相关内容。 

    二:动态SQL程序开发
      理解了动态SQL编译的原理,也就掌握了其基本的开发思想。动态SQL既然是一种”不确定”的SQL,那其执行就有其相应的特点。Oracle中提供了Execute immediate语句来执行动态SQL,语法如下:

    1 execute immediate 动态SQL语句
    2 using 绑定参数列表
    对这一语法作如下说明:

    1)动态SQL是指DDL和不确定的DML(即带参数的DML);
    2)绑定参数列表为输入参数列表,即其类型为in类型,在运行时刻与动态SQL语句中的参数(实际上占位符,可以理解为函数里面的形式参数)进行绑定;
    3)由于动态SQL是在运行时刻进行确定的,所以相对于静态而言,其更多的会损失一些系统性能来换取其灵活性。

    举例:设数据库的emp表,其数据为如下:

    ID NAME SALARY
    100 Jacky 5600
    101 Rose 3000
    102 John 4500

    1.创建该表、添加数据。 

     1 declare
     2   tablename varchar2(20); --表名
     3   field1    varchar2(20); --字段1名称
     4   datatype1 varchar2(20); --字段1类型
     5   field2    varchar2(20); --字段2名称
     6   datatype2 varchar2(20); --字段2类型
     7   field3    varchar2(20); --字段3名称
     8   datatype3 varchar2(20); --字段3类型
     9   str_sql   varchar2(500); --拼接sql语句的字符串
    10 begin
    11   tablename := 'emp';
    12   field1    := 'id';
    13   datatype1 := 'number';
    14   field2    := 'name';
    15   datatype2 := 'varchar(10)';
    16   field3    := 'salary';
    17   datatype3 := 'number';
    18   str_sql   := 'create table '||tablename||'('||field1||' '||datatype1||','||field2||' '||datatype2||','||field3||' '||datatype3|| ')';
    19   execute immediate str_sql;
    20 exception
    21   when others then
    22     dbms_output.put_line('操作失败!');
    23 end;
     1 declare
     2   v_id    number;
     3   v_name  varchar(20);
     4   v_salary number;
     5   str_sql varchar2(500); --保存拼接的sql语句
     6 begin
     7   v_id    := &vid;
     8   v_name  := '&name';
     9   v_salary:= &vsal;
    10   
    11   str_sql := 'insert into emp values(:1,:2,:3)'; --使用占位符代表变量
    12   execute immediate str_sql
    13   using v_id, v_name,v_salary; --使用变量替换sql中的占位符,v_id替换:1,v_name替换:2,依此类推。
    14   
    15   commit;
    16 end;

    2.根据大于特定的薪水的查询相应的员工信息。 

     1 create or replace procedure find_emp(p_salary number) is
     2   v_emp emp%rowtype;
     3   type my_cursor is ref cursor; 
     4   v_my_cursor my_cursor;
     5 begin
     6   open v_my_cursor for 'select * from emp where salary >:1'
     7   using p_salary;
     8   
     9   loop
    10     fetch v_my_cursor into v_emp;
    11     exit when v_my_cursor%notfound;
    12     dbms_output.put_line('薪水大于'||p_salary||' 的员工有: ');
    13     dbms_output.put_line('id为 '||v_emp.id||' 姓名为:'||v_emp.name);
    14   end loop;
    15   close v_my_cursor;
    16 end;

    3.删除指定表的数据,并通过out类型参数返回影响的行数。

    1 create or replace procedure del_rows(p_table_name in varchar2,
    2                                      p_rows_deld  out number) is
    3 begin
    4   execute immediate 'delete from '||p_table_name;
    5   p_rows_deld := sql%rowcount;
    6 end;

    注意第2个程序动态SQL语句使用了占位符“:1“,其实它相当于函数的形式参数,使用”:“作为前缀,然后使用using语句将p_salary在运行时刻将:1给替换掉,这里p_salary相当于函数里的实参。其中打开的游标为动态游标,它也属于动态SQL的范畴,其整个编译和开发的过程与execute immediate执行的过程很类似。 

    :小结

      本文对动态SQL的编译原理、开发过程进行简单介绍,对动态SQL程序开发有了一个总体的认识。

  • 相关阅读:
    第三次作业,结对编程
    第二次作业
    第一次作业
    最小环问题
    拓扑排序——烦人的幻灯片
    拓扑排序——奖金
    洛谷——P2330 [SCOI2005] 繁忙的都市
    洛谷——P2820 局域网
    最小生成树——最短网络Agri-Net
    最小生成树——城市公交网建设问题
  • 原文地址:https://www.cnblogs.com/AI-xiaocai/p/11213314.html
Copyright © 2011-2022 走看看