游标和动态SQL

游标类别:静态游标(指在编译的时候,游标就与一个select语句进行了静态绑定的游标。这样的游标仅仅能作用于一个查询语句)和动态游标(就是希望我们的查询语句在执行的时候才跟游标绑定。为了使用动态游标,必须声明游标变量)。

动态游标分两种,各自是强类型和弱类型。强类型的动态游标仅仅能支持查询结果与他类型匹配的这样的查询语句。弱类型的动态游标能够支持不论什么的查询语句。

静态游标分为两种,隐式游标和显示游标。显示游标是实用户声明和操作的一种游标。隐式游标是Oracle为全部的数据操作语句自己主动声明的一种游标。

在每一个用户的会话中,我们能够同一时候打开多个游标,这个数量有数据库初始化參数文件里的OPEN CURSORS这个參数来定义。

显示游标的使用方法步骤:

1、声明显式游标,语法:CURSOR<游标名>ISSELECT<语句>;

在声明游标的时候通常还要声明一些变量用来存放查询语句产生的查询结果。声明游标和变量都在declare中的。通常先声明变量,在声明游标。

2、打开游标,从打开游标開始。后面的步骤都是在begin和end中运行的。语法:open<游标名>;当打开游标后查询语句就開始运行了,查询结果放到Oracle的缓冲区中,然后游标指向了这个缓冲区中查询结果的第一行记录之前。

3、提取游标,通过提取游标,游标依次指向查询结果的每一行。语法:FETCH<游标名>INTO<变量列表>;

4、关闭游标。语法:CLOSE<游标名>;

演示样例:

declare
 name varchar2(50);                               --定义变量存储employees表中的内容。

department_name varchar2(20);               --定义变量存储departments表中的内容;
 cursor emp_cur IS                               --定义游标emp_cur
select name,department_name               --选出全部员工的姓名和所做部门。

from employees e,departments d
  where e.department_id=d.department_id;
begin
 open emp_cur;                                      --打开游标
 LOOP
 FETCH emp_cur INTO name,depart_name;      --将第一行数据放入变量中,游标后移。

EXIT WHEN emp_cur%NOTFOUND;
      dbms_output.put_line(name||’在’||department_name);
 END LOOP;
 CLOSE emp_cur;
END;

游标的属性:%ISOPEN,游标是否打开;%FOUND,游标是否指向有效行;%NOTFOUND。游标是否没有指向有效行;%ROWCOUNT。游标抽取过的行数。

语法:游标名%属性名。

比如:公司上市,决定给员工提高薪资。入职时间超过1年涨100。1000元封顶。

declare
 hire_date date;              --存放员工入职日期
 e_id number;                   --存放员工id
 cursor emp_cur is            --定义游标
      select id,hire_date from employees;
begin
 open emp_cur;                 --打开游标
 loop
      fetch emp_cur into e_id,hire_date       --将数据逐条存入变量
      exit when emp_cur%NOTFOUND;
      if 100*(2014-to_char(hire_date,’yyyy’))<1000 then
             update salary setsalaryvalue=salaryvalue+100*(2010-to_char(hire_date,’yyyy’)) where employee.id=e_id;
      else
             update salary setsalaryvalue=salaryvalue+1000 where employee.id=e_id;
      end if;
 end loop;
      close emp_cur;
end

使用循环游标游标的读取。语法:FOR <类型>
IN <游标名>LOOP –操作各行数据 END LOOP;

DECLARE
      CURSOR emp_cur IS
      SELECT name,department_name
      FROM employees e,departments d;
      WHERE e.department_id=d.department_id;
BEGIN
      FOR employ_record IN emp_cur LOOP
             dnms_output.put_line(employ_record.name||’在’||employee_record.department_name);
      END LOOP;
END;

隐式游标

隐式游标与显示游标的差别:1、不用声明游标。2、不用打开和关闭游标。3、必须使用INTO子句,结果仅仅能是一条。

隐式游标与显示游标的同样的:有同样的属性。隐式游标使用属性的方法是在属性名前面加上SQL%。即SQL%FOUND。SQL%ISOPEN等。

DECLARE
      name VARCHAR2(50);
      department_name varchar(20);
BEGIN
      SELECT name,department_name
      INTO name,deprtment_name
      FROM employees e,departments d;
      WHERE e.department_id=d.department_id and e.id=1;
      dbms_output.put_line(name||’在’||department_name);
END;

由于隐式游标查询结果仅仅有一行,所以假设用来计数没有多大的意义。所以%ROECOUNT这个属性经经常使用来推断插入、删除、更新是否成功,可是要在COMMIT语句之前。假设在COMMIT之后,%ROECOUNT仅仅能是0;

begin
      update employees set name=name||’A’
      where id=7;
      if sql%rowcount=1 then
             dbms_output.put_line(‘表已更新!’);
      else
             dbms_output.put_line(‘编号未找到’);
      end if;
end;

REF动态游标

ref动态游标能够在执行的时候与不同的语句进行关联。他是动态的。ref动态游标被用于处理多行的查询结果集,ref动态游标是ref类型的变量,类似于指针。

定义ref动态游标类型:type<类型名>
is ref cursor return <返回类型>;

声明ref动态游标:<游标名>
<类型名>;

打开ref动态游标:OPEN<游标名>
FOR <查询语句>;

演示样例:

DECLARE
      TYPE refcur_t IS REF CURSOR
      RETURN employess%ROWTYPE;
      refcur refcur_t;
      v_emp employees%ROWTYPE;
BEGIN
      OPEN refcur FOR
      SELECT * FROM employees;
      LOOP
             FETCH refcur INTO v_emp;
             EXIT WHEN refcur%NOTFOUND;
             dbms_output.put_line(refcur%ROWCOUNT||’‘||v_emp.name);
      END LOOP;
      CLOSE refcur;
END;

强类型ref动态游标:带有RETURN语句的REF动态游标。

弱类型ref动态游标:不带有RETURN语句的REF动态游标。

比如:

DECLARE
      TYPE refcur_t IS REF CURSOR
       refcur refcur_t;
      e_id number;
      e_name varchar2(50);
BEGIN
      OPEN refcur FOR
      SELECT id,name FROM employees;
      FETCH refcur INTO e_id,e_name;
      WHILE refcur%FOUND LOOP
             dbms_output.put_line(‘#’||e_id||’:’||e_name);
             FETCH refcur INTO e_id,e_name;
      END LOOP;
      CLOSE refcur;
END;

依据用户的输入(员工、部门)信息打印

DECLARE
      TYPE refcur_t IS REF CURSOR;
      refcur refcur_t;
      p_id NUMBER;
      p_name VARCHAR2(50);
      selection VARCHAR2(1) :=UPPER(SUBSTR(‘&tab’,1,1));
BEGIN
      IF selection = ‘E’ THEN
             OPEN refcur FOR
                    SELECT id,name FROMemployees;
             dbms_output.put_line(‘===员工信息===’);
      ELSEIF selection = ‘D’ THEN
             OPEN refcur FOR
                    SELECTdepartment_id,department_name FROM departments;
             dbms_output.put_line(‘===部门信息===’);
      ELSE
             dbms_output.put_line(‘请输入员工信息E或部门信息D’);
             RETURN;
      END IF;
      FETCH refcur INTO p_id,p_name;
      WHILE refcur%FOUND LOOP
             dbms_output.put_line(‘#’||p_id||’:’||p_name);
             FETCH refcur INTO p_id,p_name;
      END LOOP;
      CLOSE refcur;
END;

创建动态SQL语句。

静态SQL,编译时确定。

动态SQL。不编译,运行时动态确定。依据用户输入參数等才干确定SQL语句。解决PL/SQL中不支持DDL语句的问题。

创建动态DML.DDL的SQL语句语法:

EXECUTEIMMEDIATE ‘DML、DDL语句’;[INTO<变量序列>]
[USING <參数序列>];仅仅能运行返回一行或0行的语句。

假设后面的语句是个select语句。则能够使用into子句用于接收select语句选择的记录值。

能够是一个变量序列,或者一个记录型变量也就是record型的变量。假设SQL语句中有參数须要动态确定,那么我们使用USING子句。USING子句用于绑定输入的參数变量。

SQL语句中若有參数。使用”:參数名”

演示样例:动态创建表

BEGIN
      EXECUTE IMMEDIATE
             ‘CREATE TABLE bonus(id NUMBER,amtNUMBER)’;
END;

演示样例:动态查询一个员工电话

DECLARE
      sql_stmt VARCHAR2(200);
      emp_id NUMBER(10) :=’&emp_id’;
      emp_rec employees%ROWTYPE;
BEGIN
      sql_stmt :=’select * from employees WHEREid =:id’;
      EXECUTE IMMEDIATE sql_stmt INTO emp_recUSING emp_id;
END;

演示样例:动态插入记录

DECLARE
      Sql_stmt varchar2(200);
      emp_id NUMBER(10) := ‘&emp_id’;
      emp_rec employees%ROWTYPE;
BEGIN
      sql_stmt := ‘INSERT INTO employees(id)values(:id)’;
      EXECUTE IMMEDIATE sql_stmt USING emp_id;
      Dbms_output.put_line(emp.rec.phone);
END;

EXECUTEIMMEDIATE语句仅仅能返回一行或没有返回,假设编写返回多行的SQL语句,能够使用ref动态游标,他的语法:OPEN
cursor_name FOR <SQL语句> [USING <參数序列>];

演示样例:动态输出工资大于某个数额的员工信息

DECLARE
      e_id NUMBER(10);
      e_name VARCHAR2(50);
      s_salary NUMBER(8);
      TYPE c_type is REF CURSOR;
      cur c_type;
      p_salary NUMBER := ‘&p_id’;
BEGIN
      OPEN cur FOR ‘selecte.id,e.name,e.salaryvalue from employees e,salary s where e.id=s.employeeid ands.salaryvalue >:sal ORDER BY id ASC’;
      USING p_salary;
      dbms_output.put_line(‘薪水大于’||p_salary||’的员工有:’);
      LOOP
             FETCH cur INTOe_id,e_name,e_salary;
             EXIT WHEN cur%NOTFOUND;
             dbms_output.put_line(‘编号:’||e_id||’姓名:’||e_name||’薪水:’||e_salary);
END LOOP
      CLOSE cur;
END;
时间: 2024-07-31 18:45:41

游标和动态SQL的相关文章

在PL/SQL中使用游标、动态sql和绑定变量的小例子

需求:查询并输出30号部门的雇员信息 方式一:使用 loop...fetch 1 SET serveroutput ON; 2 DECLARE 3 CURSOR c_emp IS 4 SELECT * FROM emp WHERE deptno = 30; 5 v_emp emp%rowtype; 6 BEGIN 7 OPEN c_emp; 8 loop 9 fetch c_emp INTO v_emp; 10 exit WHEN c_emp%notfound; 11 dbms_output.p

ORACLE1.26 综合:游标和动态SQL

-- 假设分了4个部门(存款部,ATM部,转出,转入) --每个月定期最后1天自动生成4张表的数据 --(数据来源:deal_record) -- 第一步:先把4张表建立起来 -- 存款表 create table r1( id number primary key, card_id varchar2(18), money number ); -- 取款表 create table r2( id number primary key, card_id varchar2(18), money nu

Oracle动态游标实现动态SQL循环遍历,和静态游标的比较。

动态游标可以遍历动态的表, 格式: TYPE 游标类型 IS REF CURSOR; --定义一个动态游标游标名 游标类型; 如果查询的表的数据不同的,动态变化的,这时候可以用动态游标. 需要注意的是,动态游标的定义, 在普通存储过程中:需要放在 is 后面的第一行. 动态游标通过:open 游标 for 字符串,形式使用,遍历. create or replace procedure P_TEST_SQL is TYPE ref_cursor_type IS REF CURSOR; --定义一

动态SQL详解

动态SQL 在之前用户所编写的PL/SQL程序时有一个最大的特点:就是所操作的数据库对象(例如:表)必须存在,否则创建的子程序就会出问题,而这样的操作在开发之中被称为静态SQL操作,而动态SQL操作可以让用户在定义程序时不指定具体的操作对象,而在执行时动态的传入所需要的数据库对象,从而使程序变得更加的灵活. 创建一个功能,输入表名,输出表中有多少行,若没有这个表,则创建这个表. 首先禁用所有触发器 GRANT CREATE ANY TABLE TO SCOTT create or replace

在PL/SQL使用游标获取数据及动态SQL

1.游标概念: 当在PL/SQL块中执行DML(增删改)时,Oracle会为其分配上下文区(Context Area),游标是指向上下文区的指针 2.  游标分类: A.  隐式游标 a.  在PL/SQL中使用DML语句时自动创建隐式游标 b.  隐式游标自动声明.打开和关闭,其名为 SQL c.  通过检查隐式游标的属性可以获得最近执行的DML 语句的信息 d.  隐式游标的属性有: %FOUND – SQL 语句影响了一行或多行时为 TRUE %NOTFOUND – SQL 语句没有影响任

动态游标(例如表名作为参数)以及动态SQL分析

表名作为参数的动态游标 DECLARE v_table_name VARCHAR2(30) := 'CUX_MES_WIP_BARCODE_MAP'; --l_rec SYS_REFCURSOR; TYPE t_data IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER; TYPE t_cur IS REF CURSOR; l_data t_data; l_rec t_cur; l_cur VARCHAR2(4000); v_fm_barcode

oracle中动态SQL使用详细介绍

Oracle编译PL/SQL程序块分为两个种:通常静态SQL采用前一种编译方式,而动态SQL采用后一种编译方式,需要了解的朋友可以参考下 1.静态SQLSQL与动态SQL Oracle编译PL/SQL程序块分为两个种:其一为前期联编(early binding),即SQL语句在程序编译期间就已经确定,大多数的编译情况属于这种类型:另外一种是后期联编(late binding),即SQL语句只有在运行阶段才能建立,例如当查询条件为用户输入时,那么Oracle的SQL引擎就无法在编译期对该程序语句进

动态SQL是什么??什么是静态SQL,动态SQL的动态体现在哪里???

首先,所谓SQL的动态和静态,是指SQL语句在何时被编译和执行,二者都是用在SQL嵌入式编程中的,这里所说的嵌入式是指将SQL语句嵌入在高级语言中,而不是针对于单片机的那种嵌入式编程.在某种高级语言中,如果嵌入了SQL语句,而这个SQL语句的主体结构已经明确,例如在Java的一段代码中有一个待执行的SQL"select * from t1 where c1>5",在Java编译阶段,就可以将这段SQL交给数据库管理系统去分析,数据库软件可以对这段SQL进行语法解析,生成数据库方面

mysql动态sql 整理多个字段

原始表: 整理后的表: 方案一(动态sql): BEGIN #Routine body goes here... DECLARE v1 int(3); DECLARE v2 int(3); #DECLARE v3 VARCHAR(15); #DECLARE vcompany VARCHAR(30); #DECLARE vname VARCHAR(30); DECLARE vcol VARCHAR(30); DECLARE tmp_sql VARCHAR(3000); DECLARE vid in