oracle11g游标及触发器相关知识
『ORACLE』PLSQL动态游标的使用(11g)

『ORACLE』PLSQL动态游标的使⽤(11g)#静态游标指的是程序执⾏的时候不需要再去解析sql语⾔,对于sql语句的解析在编译的时候就可以完成的。
动态游标由于含有参数,对于sql语句的解析必须要等到参数确定的时候才能完成。
从这个⾓度来说,静态游标的效率也⽐动态游标更⾼⼀些。
#游标的相关概念: 定义: 游标它是⼀个服务器端的存储区,这个区域提供给⽤户使⽤,在这个区域⾥ 存储的是⽤户通过⼀个查询语句得到的结果集,⽤户通过控制这个游标区域当中 的指针来提取游标中的数据,然后来进⾏操作。
实质: 是⽤户在远程客户端上对服务器内存区域的操作,由数据库为⽤户提供这样的 ⼀个指针,使得⽤户能够去检索服务器内存区的数据。
#游标具有的属性:1、%ISOPEN(确定游标是否已经打开 true or false)2、%FOUND(返回是否从结果集提取到了数据 true or false)3、%NOTFOUND(返回是否从结果集没有提取到数据 true or false)4、%ROWCOUNT(返回到当前为⽌已经提取到的实际⾏数)#游标分类⼀、静态游标1、隐式游标:对于select..into...语句,⼀次只能从数据库中获取到⼀条数据,对于这种类型的DML SQL语句,就是隐式cursorselect update/insert/delete操作2、显⽰游标:由程序员定义和管理,对于从数据库中提取多⾏数据,就需要使⽤显式cursor1)定义游标---cursor [cursor name] is2)打开游标---open [cursor name]3)操作数据---fetch [cursor name]4)关闭游标---close [cursor name]⼆、REF游标1、REF 游标:动态关联结果集的临时对象。
即在运⾏的时候动态决定执⾏查询。
2、REF 游标作⽤:实现在程序间传递结果集的功能,利⽤REF CURSOR也可以实现BULK SQL,从⽽提⾼SQL性能。
Oracle中游标的用法

Oracle中游标的⽤法什么是游标?①从表中检索出结果集,从中每次指向⼀条记录进⾏交互的机制。
②关系数据库中的操作是在完整的⾏集合上执⾏的。
由 SELECT 语句返回的⾏集合包括满⾜该语句的 WHERE ⼦句所列条件的所有⾏。
由该语句返回完整的⾏集合叫做结果集。
应⽤程序,尤其是互动和在线应⽤程序,把完整的结果集作为⼀个单元处理并不总是有效的。
这些应⽤程序需要⼀种机制来⼀次处理⼀⾏或连续的⼏⾏。
⽽游标是对提供这⼀机制的结果集的扩展。
游标是通过游标库来实现的。
游标库是常常作为数据库系统或数据访问 API 的⼀部分⽽得以实现的软件,⽤来管理从数据源返回的数据的属性(结果集)。
这些属性包括并发管理、在结果集中的位置、返回的⾏数,以及是否能够在结果集中向前和/或向后移动(可滚动性)。
游标跟踪结果集中的位置,并允许对结果集逐⾏执⾏多个操作,在这个过程中可能返回⾄原始表,也可能不返回⾄原始表。
换句话说,游标从概念上讲基于数据库的表返回结果集。
由于它指⽰结果集中的当前位置,就像计算机屏幕上的光标指⽰当前位置⼀样,“游标”由此得名。
游标有什么作⽤?①指定结果集中特定⾏的位置。
②基于当前的结果集位置检索⼀⾏或连续的⼏⾏。
③在结果集的当前位置修改⾏中的数据。
④对其他⽤户所做的数据更改定义不同的敏感性级别。
⑤可以以编程的⽅式访问数据库。
⼀、游标:1、概念:游标的本质是⼀个结果集resultset,主要⽤来临时存储从数据库中提取出来的数据块。
⼆、游标的分类:1、显式游标:由⽤户定义,需要的操作:定义游标、打开游标、提取数据、关闭游标,主要⽤于对查询语句的处理。
属性:%FOUND %NOTFOUND %ISOPEN %ROWCOUNTExample:打印emp表的员⼯信息DECLARECURSOR emp_cursor IS SELECT empno,ename,job FROM emp;v_empno emp.empno%TYPE;v_name emp.ename%TYPE;v_job emp.job%TYPE;BEGINOPEN emp_cursor;LOOPFETCH emp_cursor INTO v_empno,v_name,v_job;DBMS_OUTPUT.PUT_LINE('员⼯号为:'||v_empno||'姓名是'||v_name||'职位:'||v_job);EXIT WHEN emp_cursor%NOTFOUND;END LOOP;CLOSE emp_cursor;END;这⾥严格按照显⽰游标的书写规则:DECLARE emp_cursor定义游标OPEN emp_cursor打开游标FETCH emp_cursor INTO...提取数据CLOSE emp_cursor关闭游标,因为提取出来的数据属于多⾏,所以通过loop循环打印即可。
Oracle触发器(trigger)

Oracle触发器(trigger)触发器是许多关系数据库系统都提供的⼀项技术。
在ORACLE系统⾥,触发器类似过程和函数,都有声明,执⾏和异常处理过程的PL/SQL 块。
1 触发器类型触发器在数据库⾥以独⽴的对象存储,它与存储过程和函数不同的是,存储过程与函数需要⽤户显⽰调⽤才执⾏,⽽触发器是由⼀个事件来启动运⾏。
即触发器是当某个事件发⽣时⾃动地隐式运⾏。
并且,触发器不能接收参数。
所以运⾏触发器就叫触发或点⽕(firing)。
ORACLE事件指的是对数据库的表进⾏的INSERT、UPDATE及DELETE操作或对视图进⾏类似的操作。
ORACLE将触发器的功能扩展到了触发ORACLE,如数据库的启动与关闭等。
所以触发器常⽤来完成由数据库的完整性约束难以完成的复杂业务规则的约束,或⽤来监视对数据库的各种操作,实现审计的功能。
1.1 DML触发器ORACLE可以在DML语句进⾏触发,可以在DML操作前或操作后进⾏触发,并且可以对每个⾏或语句操作上进⾏触发。
1.2 替代触发器由于在ORACLE⾥,不能直接对由两个以上的表建⽴的视图进⾏操作。
所以给出了替代触发器。
它就是ORACLE 8专门为进⾏视图操作的⼀种处理⽅法。
1.3 系统触发器 ORACLE 8i 提供了第三种类型的触发器叫系统触发器。
它可以在ORACLE数据库系统的事件中进⾏触发,如ORACLE系统的启动与关闭等。
触发器组成:触发事件:引起触发器被触发的事件。
例如:DML语句(INSERT, UPDATE, DELETE语句对表或视图执⾏数据处理操作)、DDL语句(如CREATE、ALTER、DROP语句在数据库中创建、修改、删除模式对象)、数据库系统事件(如系统启动或退出、异常错误)、⽤户事件(如登录或退出数据库)。
触发时间:即该TRIGGER 是在触发事件发⽣之前(BEFORE)还是之后(AFTER)触发,也就是触发事件和该TRIGGER 的操作顺序。
Oracle数据库的函数,存储过程,程序包,游标,触发器

Oracle数据库的函数,存储过程,程序包,游标,触发器Oracle⾃定义函数函数的主要特性是它必须返回⼀个值。
创建函数时通过 RETURN ⼦句指定函数返回值的数据类型。
函数的⼀些限制:●函数只能带有 IN 参数,不能带有 IN OUT 或 OUT 参数。
●形式参数必须只使⽤数据库类型,不能使⽤ PL/SQL 类型。
●函数的返回类型必须是数据库类型Create function 函数名称 return 返回值类型 asBegin····End 函数名称;--创建不带参数函数,返回t_book中书的数量create function getBookCount return number asbegindeclare book_count number;beginselect count(*) into book_count from t_book;return book_count;end;end getBookCount;--函数调⽤set serveroutput on;begindbms_output.put_line('表t_book中有'||getBookCount()||'本书');end;--创建带参数函数,查找某个表的记录数create function getTableCount(table_name varchar2) return number asbegindeclare recore_count number;query_sql varchar2(300);--定义sql语句beginquery_sql:='select count(*) from '||table_name;--execute immediate:⽴即执⾏该SQL语句execute immediate query_sql into recore_count;return recore_count;end;end getTableCount;--函数调⽤set serveroutput on;begindbms_output.put_line('表中有'||getTableCount('t_book_log')||'条数据');end;CREATE OR REPLACE FUNCTION item_price_rage (price NUMBER)/* 参数、指定返回类型 */RETURN varchar2AS/* 定义局部变量 */min_price NUMBER;max_price NUMBER;BEGINSELECT MAX(ITEMRATE), MIN(ITEMRATE) INTO max_price, min_priceFROM itemfile;IF price >= min_price AND price <= max_price THENRETURN '输⼊的单价介于最低价与最⾼价之间';ELSERETURN '超出范围';END IF;END;匿名块执⾏函数p NUMBER := 300;MSG varchar2(200);BEGINMSG := item_price_range(p);DBMS_OUTPUT.PUT_LINE(MSG);END;SELECT查询调⽤(因为函数必须有返回值)SELECT myfunction FROM dual;Oracle存储过程存储过程(Stored Procedure),就是⼀组⽤于完成特定功能的SQL语句集,该SQL语句集经过编译后存储在数据库中。
Oracle触发器详解

Oracle触发器详解开发中肯定会⽤到Oracle的触发器,本⽂进⾏详细讲解。
这⾥实例中⽤到的主要是Oracle中scott⽤户下的emp以及dept表,数据如下⼀、触发器概念1、概念:触发器的本质是⼀个存储过程,顾名思义发⽣特定事件时Oracle会执⾏触发器中的代码。
细分它的组成可以分为3个部分:第⼀部分在什么条件下触发器会执⾏,即触发器被触发的事件。
第⼆部分在什么时间点执⾏触发器即触发器的发⽣事件例如before,after。
第三部分触发器⾃⾝所要做的事情,就是触发器被触发以后具体想表达的事件,在begin和end之间的sql。
⼆、触发器的分类:1、ddl触发器:即执⾏ddl操作后所触发的事件。
常⽤的ddl操作有:grant(授权),revoke(撤销授权),create(创建),drop(删除),alter(修改),comment(注释),audit(审核),rename(重命名)在进⾏具体实例以前先来讲解另⼀个概念:oracle中的user和schema:user:oracle中的⽤户,拥有数据库的对象以及对数据库对象增删改查的权限。
schema:该⽤户下所有数据库对象的集合Collection.类似于⽣活中房⼦schema和房⼦的拥有者user之间的关系,你是⼀个⽤户user你可以通过alter session查看别⼈的房⼦,但是你是否可以改变房⼦中的家具,要看这个房⼦的拥有者是否grant你这个权限,除⾮你是所有房⼦的最⾼权限⼈dba。
ddl Example:禁⽌scott⽤户的所有ddl操作CREATE OR REPLACE TRIGGER scott_triggerBEFORE DDLON SCHEMABEGINRAISE_APPLICATION_ERROR(-20008,'禁⽌scott⽤户的所有ddl操作');END;create sequence myseq;这⾥看到在创建触发器以后如果仍然使⽤ddl操作,便会报错。
oracle中游标的用法

Oracle中游标的用法1. 引言在Oracle数据库中,游标(Cursor)是一种用于处理查询结果集的机制。
通过使用游标,我们可以在应用程序中对查询结果集进行遍历、操作和管理。
本文将详细介绍Oracle中游标的用法,包括游标的定义、声明、打开、关闭以及使用游标进行数据检索和更新等操作。
2. 游标的定义与声明在Oracle数据库中,我们可以使用DECLARE语句来定义和声明游标。
以下是一个简单的示例:DECLARECURSOR cursor_name IS SELECT column1, column2 FROM table_name;在上述示例中,cursor_name是游标的名称,SELECT column1, column2 FROMtable_name是一个SQL查询语句,它指定了要从哪个表中检索数据。
3. 游标的打开与关闭在使用游标之前,我们需要先打开它。
要打开一个游标,我们可以使用OPEN语句。
以下是一个示例:OPEN cursor_name;当我们完成对游标的操作后,需要关闭它以释放资源。
要关闭一个游标,我们可以使用CLOSE语句。
以下是一个示例:CLOSE cursor_name;注意,在关闭一个已经被打开的游标之前,我们必须先确保已经完成了对其所有操作。
4. 使用游标进行数据检索一旦我们定义、声明并打开了一个游标,我们就可以使用它来检索数据。
在Oracle中,我们可以使用FETCH语句对游标中的数据进行逐行检索。
以下是一个示例:FETCH cursor_name INTO variable1, variable2;在上述示例中,variable1和variable2是用于接收查询结果的变量。
当我们需要遍历整个结果集时,可以使用循环结构来连续地检索数据。
以下是一个示例:DECLARECURSOR cursor_name IS SELECT column1, column2 FROM table_name;variable1 table_name.column1%TYPE;variable2 table_name.column2%TYPE;BEGINOPEN cursor_name;LOOPFETCH cursor_name INTO variable1, variable2;EXIT WHEN cursor_name%NOTFOUND; -- 当没有更多的数据可检索时退出循环-- 在这里执行对查询结果的操作END LOOP;CLOSE cursor_name;END;在上述示例中,我们使用了一个无限循环,并在每次迭代中通过FETCH语句将查询结果赋值给变量。
oracle数据库 游标、存储过程和触发器

游标的基本概念 使用显式游标
(1)说明游标。 (2)打开游标。 (3)读取数据。 (4)关闭游标。
游标的基本概念
隐式游标
【例】使用SELECT语句声明隐式游标,从 HR.Departments表中读取Department_name字段的 值到变量DepName:
SET ServerOutput ON; DECLARE DepName HR.Departments.Department_Name%Type; BEGIN SELECT Department_name INTO DepName FROM HR.Departments WHERE Department_ID=10; dbms_output.put_line(DepName); END;
游标FOR循环
BEGIN --开始程序体 IF MyCur%ISOPEN = FALSE Then OPEN MyCur(1); END IF; LOOP FETCH MyCur INTO var_UserRecord; --读取当前游标位置的数 据到记录变量var_UserRecord EXIT WHEN MyCur%NOTFOUND; --当游标指向结果集结尾时 退出循环 /* 显示保存在记录变量var_UserRecord中的数据 */ dbms_output.put_line('用户编号:' || var_erId ||', 用户名::' || var_erName); END LOOP; CLOSE MyCur; --关闭游标 END; --结束程序体
游标FOR循环
【例】声明记录类型User_Record_Type和定义记 录变量var_UserRecord:
TYPE User_Record_Type IS RECORD ( UserId erId%Type, UserName erName%Type); var_UserRecord User_Record_Type;
Oracle11g基础入门理论

06
Oracle 11g的常见问题与解决方案
启动与关闭数据库的问题
总结词:Oracle 11g数据库启动与关闭过程中可能遇到的问题及解决方案。
检查日志文件,查找错误信息,可能是由于配置文件、磁盘空间不足等原因导致。
05
Oracle 11g的安全性管理
用户权限管理是Oracle 11g数据库安全性管理的重要环节,它确保了数据库的安全和数据的完整性。
用户权限管理
数据备份与恢复是Oracle 11g数据库安全性管理的另一个重要环节,它确保了数据的安全性和可靠性。
数据恢复则是将备份介质上的数据、日志等文件重新加载到数据库中,以恢复数据。
高可用性
Oracle 11g具备强大的安全性功能,包括数据加密、访问控制、审计等,保护企业数据不被非法访问和篡改。
安全性
Oracle 11g支持大规模并行处理和自动性能优化,能够应对企业不断增长的数据和业务需求。
可扩展性
Oracle 11g与之前的版本兼容,企业可以平滑升级并保留原有投资。
兼容性
Oracle 11g的特点
数据重复或遗漏
检查数据是否出现重复或遗漏的情况,确保数据的完整性。
数据完整性问题
THANKS FOR
WATCHING
感谢您的观看
优化启动参数,减少不必要的检查,缩短启动时间。
启动与关闭数据库的问题
启动时间过长
数据库启动失败
启动与关闭数据库的问题
数据库无法正常关闭
检查是否有未完成的事务或进程,确保所有用户已断开连接。
关闭时间过长
优化关闭参数,减少不必要的检查,缩短关闭时间。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
oracle11g 游标:1. 当在PL/SQL中使用SQL语句时,Oracle会为其分配上下文区域,这是一段私有的内存区域,用于暂时保存SQL语句影响到的数据。
游标是指向这段内存区域的指针。
2. Oracle中主要有两种类型的游标:(1) 隐式游标:所有的DML语句和PL/SQL SELECT 语句都有;(2) 显式游标:由开发人员声明和控制。
3. 可以使用的游标属性包括四种:%ROWCOUNT、%FOUND、%NOTFOUND、%ISOPEN,这四种属性对于显式游标和隐式游标都有用,但是含义和使用方法略有不同。
游标在使用属性时,需要以游标名称作为前缀,以表明该属性是哪个游标的,隐式游标没有名称,所以在使用隐式游标时采取了统一的一个名称SQL。
4. 在PL/SQL中的SELECT语句只能且必须取出一行数据,取出多行或者零行都被认为是异常,所以在对多行数据进行操作时,必须使用显式游标来实现。
5. 使用显式游标的步骤:(1)声明游标:CURSOR cursor_name is select_statement;(2)打开游标:OPEN cursor_name;(3)取游标中的数据:FETCH cursor_name INTO variable1,variable2,...;(4)关闭游标:CLOSE cursor_name;6.用变量接收游标中的数据sql> declarev_name emp.ename%TYPE;v_sal emp.sal%TYPE;cursor emp_cursor is select ename,sal from empwhere deptno=10;beginopen emp_cursor;loopfetch emp_cursor into v_name,v_sal;exit when emp_cursor%NOTFOUND;dbms_output.put_line(v_name || ‘的薪水是’ || v_sal);end loop;dbms_output.put_line(‘共取出了’ || emp_cursor%ROWCOUNT || ‘条记录’);close emp_cursor;end;7.通常简单LOOP循环与%NOTFOUND属性配合使用,而WHILE循环与%FOUND属性配合使用。
8.使用记录接收游标中的数据sql> declarecursor emp_cursor is select ename, sal from empwhere deptno=10;--注意创建记录类型的方式emp_record emp_cursor%ROWTYPE;beginopen emp_cursor;loopfetch emp_cursor into v_name,v_sal;exit when emp_cursor%NOTFOUND;dbms_output.put_line(v_name || ‘的薪水是’ || v_sal);end loop;dbms_output.put_line(‘共取出了’ || emp_cursor%ROWCOUNT || ‘条记录’);close emp_cursor;end;9.带有参数的游标的语法:CURSOR cursor_name[(parameter_name datatype,...)]ISselect_statement;10.sql> declarecursor emp_cursor(v_deptno NUMBER) isselect ename,sal from emp where deptno=v_deptno;emp_record emp_cursor%ROWTYPE;beginopen emp_cursor(20);loopfetch emp_cursor into emp_record;exit when emp_cursor%NOTFOUND;dbms_output.put_line(emp_ || ‘的薪水是’ || emp_cursor.sal);end loop;dbms_output.put_line(‘共取出了’ || emp_cursor%ROWCOUNT || ‘条记录’);close emp_cursor;end;11.游标变量:也叫做动态游标,通过REF CURSOR方式定义,它仍然是指向一段SQL语句的内存地址的指针。
和动态游标相比,之前在声明时就定义好SELECT语句的游标称作静态游标,而动态游标在打开时才指定其所对应的SELECT语句。
12.sql> declare--定义游标变量类型type dept_cursor_type is ref cursorreturn dept%ROWTYPE--定义游标变量dept_cursor dept_cursor_type;--定义记录类型dept_record dept%ROWTYPE;beginopen dept_cursor for select deptno,dname,locfrom dept;fetch dept_cursor into dept_record;while dept_cursor%FOUND loopdbms_output.put_line(dept_record.deptno||’,’||dept_record.dname||’,’||dept_record.loc);fetch dept_cursor into dept_record;end loop;dbms_output.put_line(‘GAME OVER’);end;以上定义的游标变量中指定了返回类型,也就是说,游标对应的结果集必须按照返回类型的规定来定义,这种游标称作强类型游标变量,除此之外还有一种弱类型游标变量。
13.游标的FOR循环:for record_name in cursor_name loopstatement1;statement2;…end loop;14.declarecursor emp_cursor(v_deptno NUMBER) isselect ename,sal from emp where deptno=v_deptno;beginfor emp_record in emp_cursor(20) loopdbms_output.put_line(emp_record.ename||’的薪水是’||emp_record.sal); end loop;end;15.cursor cursor_name is select_statementfor update [of column_reference][nowait]在游标结果集上加锁,NOWAIT子句指定不等待锁,也就是如果要加锁的数据已经被锁定,则不等待直接返回。
将显示游标行中的当前行修改或者删除,更新或删除的语法如下:update table_name set column=..where current of cursor_name;delete from table_name where current of cursor_name;oracle11g 触发器:1. PL/SQL程序中的触发器的结构类似于函数和过程,同样是具有声明部分、执行部分和异常处理部分的命名PL/SQL块。
但与过程和函数不同的是,触发器是在事件发生时隐式地运行的,并且触发器不能接收参数,而过程和函数都是被用户显式的调用的。
2. 运行触发器的方式叫触动,或者点火(触发),是指在指定的事件发生的时候(前或者后)自动运行定义的PL/SQL块。
3. 在ORACLE数据库中主要有三种触发器类型:(1) DML触发器,由表上执行的INSERT、UPDATE、DELETE操作触发;(2) INSTEAD OF替代触发器,用于视图的操作;(3)系统触发器,用于系统事件触发。
4. 触发器的触发范围又分为行级触发器和语句级触发器。
5. 在Oracle数据库中,触发器主要用于下列情况:(1) 安全性方面,确定用户的操作是否可以继续进行;(2) 产生对数据值修改的审计,将修改的信息记录下来,产生数据改动记录;(3) 提供更灵活的完整性校验规则,能够根据更复杂的规则校验数据;(4) 提供表数据的同步复制,使多个表的数据达到同步;(5) 事件日志记录,记录数据库的重要操作信息。
6. 创建语句级触发器的语法格式:CREATE [OR REPLACE] TRIGGER trigger_nametimingevent1 [OR event2 OR event3]ON table_namewhen conditionstrigger_body7. SQL>CREATE OR REPLACE TRIGGER secure_empBEFORE INSERT ON empBEGINIF(TO_CHAR(SYSDATE,’DY’) IN (‘星期六’,’星期日’)) OR (TO_CHAR(SYSDATE,’HH24:MI’) NOT BETWEEN ‘8:00’ AND ’18:00’) THENRAISE_APPLICATION_ERROR(-20500,’你只有在工作时间对EMP表执行插入操作!’);END IF;END;8. RAISE_APPLICATION_ERROR(error_number_in IN NUMBER,error_msg_in INVARCHAR2);(error_number_in的取值范围是-20000—20999之间,error_msg_in的长度不能超过2K,否则截取前面的2K),是一个系统存储过程,作用是将应用程序的错误从服务器端传递到客户端应用程序。
9. SQL> SQL>CREATE OR REPLACE TRIGGER secure_empBEFORE INSERT OR UPDATE OR DELETE ON empBEGINIF(TO_CHAR(SYSDATE,’DY’) IN (‘星期六’,’星期日’)) OR (TO_CHAR(SYSDATE,’HH24:MI’) NOT BETWEEN ‘8:00’ AND ’18:00’) THENIF DELETING THENRAISE_APPLICATION_ERROR(-20500,’你只有在工作时间对EMP表执行删除操作!’);ELSEIF INSERTING THENRAISE_APPLICATION_ERROR(-20500,’你只有在工作时间对EMP表执行插入操作!’);ELSEIF UPDATING(‘SAL’) THENRAISE_APPLICATION_ERROR(-20500,’你只有在工作时间对EMP表执行更新操作!’);END IF;END IF;END;10. 创建行级触发器的语法格式:CREATE [OR REPLACE] TRIGGER trigger_nametimingevent1 [OR event2 OR event3]ON table_name[REFERENCING OLD AS old|NEW AS new]FOR EACH ROW[WHEN (condition)]Trigger_body其中REFERENCING子句是声明触发器替换前后的引导前缀名的,默认替换前的前缀名为OLD,替换后的前缀名为NEW,也可以自己声明替换前后的变量前缀规则。