㈠ 请写出游标和存储过程的概念及其在数据库编程中发挥什么样的作用
转载
以下记录的上由于工作需要写的Oracle的<br>使用游标的储存过程,个人觉得比较有代表性。希望给初学者一定的帮助,也给自己加深一下印象。
在ORACLE中,他以一个语句块为一个默认的事务。也就是说,如果你就单单只执行一段ORACLE的语句块,他默认是以事务的形式执行的。
01 CREATE OR REPLACE PROCEDURE sp_EditInlayOut(
02 FID NUMBER, --修改记录的ID T_INLAYOUT表的主键
03 InlayBoxIDs varchar2, --修改的记录
04 BoxCount number, --装箱数量
05 ApplyUserID varchar2, --申请人编号
06 StoreUserID varchar2, --库管编号
07 ConfirmState char, --确认状态
08 ExistState char, --存在状态
09 strErr OUT varchar2 --存储过程执行结果。成功返回空,失败返回错误原因
10 )
11 AS
12 --定义变量
13 v_Now DATE;
14 v_Now2 date;
15 v_LogID number;
16 v_ChipID number;
17 v_sql varchar2(2000);
18 BEGIN
19
20 --记录日志
21 INSERT INTO T_InlayOut_Log(F_InlayBoxIDs,f_Boxcount,f_Applyuserid,f_Storeuserid,f_Addtime,f_Confirmstate
22 ,f_Existstate, f_modifyid, f_modifytime, f_modifyuserid )
23 ((SELECT F_InlayBoxIDs,f_Boxcount,f_Applyuserid,f_Storeuserid,f_Addtime,f_Confirmstate,f_Existstate
24 ,FID,SYSDATE,StoreUserID FROM T_InlayOut WHERE F_ID=FID));
25 --取刚插入记录的ID
26 select seq_t_inlayout_log.currval into v_LogID from al;
27 --定义游标
28 DECLARE CURSOR myCusor IS SELECT F_ID FROM T_CHIP WHERE F_InlayBoxID IN (SELECT f_ID FROM
29 T_InlayBox where F_InlayOutID = FID);
30 --开始使用游标取数据
31 BEGIN
32 OPEN myCusor;
33
34 LOOP
35 FETCH myCusor INTO v_ChipID;
36 --游标取不到数据则退出
37 EXIT WHEN myCusor%NOTFOUND;
38
39 SELECT MIN(F_CurrentTime) INTO v_Now FROM t_Chipstatehistory WHERE
40 (F_HistoryState = 'Confirm_InlayIn') AND F_ChipID = v_ChipID;
41 --改变芯片表的状态
42 UPDATEt_chip SET f_State = 'Confirm_InlayIn',F_CompareTime = v_Now WHERE F_ID = v_ChipID;
43 --保存芯片状态历史记录
44 INSERT INTO T_CHIPSTATEHISTORY(f_chipid, f_Historystate,F_TABLEID,f_Currenttime,F_TABLENAME)
45 VALUES
46 (v_ChipID,'Confirm_InlayIn',v_LogID,SYSDATE,'T_InlayOut_Log');
47
48 END LOOP;
49 CLOSE myCusor;
50 END;
51
52 --选择最近芯片状态变更时间
53 --SELECT MIN(F_CURRENTTIME) INTO v_NOW FROM T_CHIPSTATEHISTORY WHERE F_HISTORYSTATE = 20
54 AND F_CHIPID IN (SELECT F_ID FROM T_CHIP WHERE F_InlayBoxID=(SELECT F_ID FROM T_InlayBox
55 WHERE F_InlayOutID=FID));
56
57 --将芯片表中芯片状态更新到以前状态
58 --UPDATE T_CHIP SET F_State=20,F_CompareTime=v_NOW WHERE F_InlayBoxID IN (SELECT F_ID FROM
59 T_InlayBox WHERE F_InlayOutID =FID);
60 --记录芯片状态变更日志
61 --INSERT INTO T_ChipStateHistory (F_ChipID,f_Historystate,f_Tableid,f_Currenttime,f_Tablename)VALUES
62 --((SELECT F_ID FROM T_CHIP WHERE F_InlayBoxID=(SELECT F_ID FROM T_InlayBox WHERE F_InlayOutID=FID)),
63 20,v_LogID,SYSDATE,'T_InlayOut_Log');
64
65
66 --将Inlay出库箱表中以前的数据更新到以前状态
67 UPDATE T_InlayBox SET F_State=2,F_InlayOutID=null WHERE F_InlayOutID =FID;
68
69 --编辑时将新的INLAY出库信息更新
70 UPDATE T_InlayOut SET F_InlayBoxIDs=InlayBoxIDs,f_Boxcount=BoxCount,f_Applyuserid=ApplyUserID,
71 f_Storeuserid=StoreUserID,f_Confirmstate=ConfirmState,F_ExistState=ExistState,F_ConfirmTime=null
72 WHERE F_ID=FID;
73
74 --更新T_InlayBox 新的状态
75 --UPDATE T_InlayBox SET F_State=3,F_InlayOutID=FID WHERE F_ID in (InlayBoxIDs);
76 v_sql := 'UPDATE T_InlayBox SET F_State=3,F_InlayOutID='||FID||' WHERE F_ID in ('||InlayBoxIDs||')';
77 --立即执行v_sql
78 EXECUTE IMMEDIATE v_sql;
79
80 SELECT SYSDATE INTO v_Now2 FROM DUAL;
81 --更新芯片表状态
82 UPDATE T_Chip SET F_State='No_Confirm_InlayOut',F_CompareTime=v_Now2 WHERE F_InlayBoxID IN
83 (SELECT F_ID FROM T_InlayBox WHERE F_InlayOutID=FID);
84 --记录当前操作日志
85 INSERT INTO T_ChipStateHistory (F_ChipID,f_Historystate,f_Tableid,f_Currenttime,f_Tablename)
86 SELECT F_ID,'No_Confirm_InlayOut',v_LogID,v_Now2,'T_InlayOut_Log' FROM T_CHIP WHERE F_InlayBoxID IN
87 (SELECT F_ID FROM T_InlayBox WHERE F_InlayOutID=FID);
88 --提交
89 COMMIT;
90 --发生异常时返回错误码
91 EXCEPTION
92 WHEN OTHERS THEN
93 strErr := substr(sqlerrm,1,100);
94 ROLLBACK;
95 END sp_EditInlayOut;
但是在SQLSERVER中,除非你将所有的T-SQL语句块以显示的方式【BEGIN TRANSACTION ....END TRANSACTION】申明在事务中,否则SQLSERVER会将语句块中的每一句作为一个单独的默认事务执行。
此外,游标是一种比较占I/O资源的操作,使用完后应该及时关闭,以释放系统资源。
㈡ 存储过程为什么要用游标,什么情况下使用游标
游标一般用于把通过脚本得到的结果集的内容在用于其它的SQL语句中。但是游标执行会影响脚本执行速度,所以使用时请慎重。 在存储过程或触发器中使用 SQL 游标的典型过程为: 声明SQL 变量包含游标返回的数据。为每个结果集列声明一个变量。声明足够大的变量来保存列返回的值,并声明变量的类型为可从列数据类型隐式转换得到的数据类型。
使用 DECLARE CURSOR 语句将 SQL 游标与 SELECT 语句相关联。另外,DECLARE CURSOR 语句还定义游标的特性,例如游标名称以及游标是只读还是只进。
使用 OPEN 语句执行 SELECT 语句并填充游标。
使用 FETCH INTO 语句提取单个行,并将每列中的数据移至指定的变量中。然后,其他 SQL 语句可以引用那些变量来访问提取的数据值。SQL 游标不支持提取行块。
使用 CLOSE 语句结束游标的使用。关闭游标可以释放某些资源,例如游标结果集及其对当前行的锁定,但如果重新发出一个 OPEN 语句,则该游标结构仍可用于处理。由于游标仍然存在,此时还不能重新使用该游标的名称。DEALLOCATE 语句则完全释放分配给游标的资源,包括游标名称。释放游标后,必须使用 DECLARE 语句来重新生成游标。
请采纳。
㈢ 游标属于存储过程吗
存储过程就是可以传入参数进行一定的内部运算,然后再传出结果,比视图要复杂点,但功能会很多的。。游标就是在存储过程中,会对中间表的每一行数据进行读取,然后其他操作,现在一般不讲究游标了,基本上游标都可以用别的代替,可以多用连接
㈣ 存储过程跟游标之间有什么关联么
两者没有什么必然的联系
游标一般不单独使用,可以在存储过程\函数等中使用,使用完后要关闭释放。
存储过程可以是一个对象,存储起来,下次再调用。
㈤ 6、什么是存储过程什么是游标,何时使用、何时不用游标
存储过程是一组命名了的SQL语句集合,是为了完成特定功能汇集而成的。该集合编译后存放在数据库中,可根据实际情况重新编译,可直接运行,也可远程运行且存储过程直接在服务器端运行。
游标实际上是一种能从包括多条数据记录的结果集(结果集是select查询之后返回的所有行数据的集合)中每次提取一条记录的机制充当指针的作用,遍历结果中的所有行,但他一次只指向一行。
游标在循环处理字段的时候使用
建议:尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写;使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效;与临时表一样,游标并不是不可使用。
㈥ 存储过程中用什么可以替代游标
Mysql存储过程优化——使用临时表代替游标。
Mysql游标在操作小数据量时比较方便,效率可观,但操作大数据量,速度比较慢,甚至直接产生系统错误。
一般说来,当操作的数据超过1万条时,就避免用游标吧。
为了测试游标性能,写了下面一个游标对IDC_Gather_Info表中数据进行遍历
1.数据量15万,执行成功,耗时8.928s
2.数据量5万,执行成功,耗时2.994s
3.数据量1万,执行成功,耗时0.634s
可以看到Mysql的游标在处理大一点的数据量时还是比较乏力的,仅适合用于操作几百上千的小数据量。
㈦ 在存储过程中,为了在一个结果集的记录中进行循环,除了用游标还能用其他的方式吗
临时表 或表变量都可以 例如:sqlserver数据库,你的结果集为 T_Table
if object_id('tempdb..#tmp') > 0
drop table #tmp
declare @ID int
select identity(int,1,1) as ID,* from T_Table
select @ID = 1
while Exists(select * from #tmp)
begin
select @变量 = 字段 from #tmp where id = @id
select @ID = @ID + 1
end
将临时表 换成表变量也可以
不用游标可以避免 游标的释放问题和游标重名的问题。
如果只是为了速度 就无所谓了,游标的性能没有大家说的那么差,关键就看你怎么写就是了
没有环境,自己调整一下吧
㈧ 存储过程,如果不用游标,可以用什么代替
少用游标。尽量用一条sql语句代替。或者用多条SQL语句分批处理。有时间多看看开窗语句,很实用。
㈨ db2的存储过程的游标cursor怎么替换
db2的存储过程的游标cursor替换的解决方法如下:
在sql server 里可以用 临时表,表变量等 .
可以将复合条件的记录都插入到临时表,然后再用 update 等语句对临时表进行计算.
最后将临时表的数据插入到正式表.
其实你这个需求 ,是可以不用触发器的.
多写几个 insert ,update 就是了。存储过程中不是非要用游标啊,他有输入和输出参数,只要在过程中做相应的处理就会返回输出参数。游标的作用主要是为了循环提取数据,游标分隐性游标和显性游标。 举个例子(显性游标): cursor 游标名 is select 语句; while 游标名% found loop end loop;其中的select 语句提取的是一列值,然后每次取一个进行下面的循环。 (隐性游标): for 游标名 in (select 语句)loop end loop;其中的select 语句提取的也是一列值,然后每次取一个进行下面的循环。
㈩ oracle 游标能用别的替换或者如何使游标的
你说的资料上说的尽量不使用游标,那就是使用动态sql+execute immediate的方式了。这主要是程序设计上的问题,比如说一些表名或者字段名,可以使用变量来代替,这样写程序的时候麻烦点,但是方便日后维护。取数据用游标没什么错误,看你的存储过程,重要的是还是优化sql。或者可以使用bulk collect 批量的方式取数据。