oracle 游标是做啥用的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle 游标是做啥用的相关的知识,希望对你有一定的参考价值。
oracle中游标是做什么用的?初学者,最好能具体点,简单点,谢谢了!
游标(CURSOR)也叫光标,在关系数据库中经常使用,在PL/SQL程序中可以用CURSOR与SELECT一起对表或者视图中的数据进行查询并逐行读取。Oracle游标分为显示游标和隐式游标。
显示游标(Explicit Cursor):在PL/SQL程序中定义的、用于查询的游标称作显示游标。
隐式游标(Implicit Cursor):是指非PL/SQL程序中定义的、而且是在PL/SQL中使用UPDATE/DELETE语句时,Oracle系统自动分配的游标。
一.显示游标
1.使用步骤
(1)定义 (2)打开 (3)使用 (4)关闭
2.使用演示
首先创建测试用表STUDENT,脚本如下:
CREATE TABLE "STUDENT" (
"STUNAME" VARCHAR2(10 BYTE),
"STUNO" VARCHAR2(4 BYTE),
"AGE" NUMBER,
"GENDER" VARCHAR2(2 CHAR)
)
(1).使用WHILE循环处理游标
create or replace PROCEDURE PROC_STU1 AS
BEGIN
--显示游标使用,使用while循环
declare
--1.定义游标,名称为cur_stu
cursor cur_stu is
select stuno,stuname from student order by stuno;
--定义变量,存放游标取出的数据
v_stuno varchar(4);
v_stuname varchar(20);
begin
--2.打开游标cur_stu
open cur_stu;
--3.将游标的当前行取出存放到变量中
fetch cur_stu into v_stuno,v_stuname;
while cur_stu%found --游标所指还有数据行,则继续循环
loop
--打印结果
dbms_output.PUT_LINE(v_stuno||'->'||v_stuname);
--继续将游标所指的当前行取出放到变量中
fetch cur_stu into v_stuno,v_stuname;
end loop;
close cur_stu; --4.关闭游标
end;
END PROC_STU1;
(2).使用IF..ELSE代替WHILE循环处理游标
create or replace PROCEDURE PROC_STU2 AS
BEGIN
--显示游标使用,使用if判断
declare
--1.定义游标,名称为cur_stu
cursor cur_stu is
select stuno,stuname from student order by stuno;
--定义变量,存放游标取出的数据
v_stuno varchar(4);
v_stuname varchar(20);
begin
--2.打开游标cur_stu
open cur_stu;
--3.将游标的当前行取出存放到变量中
fetch cur_stu into v_stuno,v_stuname;
loop
if cur_stu%found then --如果游标cur_stu所指还有数据行
--打印结果
dbms_output.PUT_LINE(v_stuno||'->'||v_stuname);
--继续将游标所指的当前行取出放到变量中
fetch cur_stu into v_stuno,v_stuname;
else
exit;
end if;
end loop;
close cur_stu; --4.关闭游标
end;
END PROC_STU2;
(3).使用FOR循环处理游标
create or replace PROCEDURE PROC_STU3 AS
BEGIN
--显示游标使用,使用for循环
declare
--定义游标,名称为cur_stu
cursor cur_stu is
select stuno,stuname from student order by stuno;
begin
for stu in cur_stu
loop
dbms_output.PUT_LINE(stu.stuno||'->'||stu.stuname);
--循环做隐含检查 %notfound
end loop;
--自动关闭游标
end;
END PROC_STU3;
(4).常用的使用EXIT WHEN处理游标
create or replace
PROCEDURE PROC_STU1_1 AS
BEGIN
--显示游标使用,使用exit when循环
declare
--1.定义游标,名称为cur_stu
cursor cur_stu is
select stuno,stuname from student order by stuno;
--定义变量,存放游标取出的数据
v_stuno varchar(4);
v_stuname varchar(20);
begin
--2.打开游标cur_stu
open cur_stu;
loop
--3.将游标的当前行取出存放到变量中
fetch cur_stu into v_stuno,v_stuname;
exit when cur_stu%notfound; --游标所指还有数据行,则继续循环
--打印结果
dbms_output.PUT_LINE(v_stuno||'->'||v_stuname);
end loop;
close cur_stu; --4.关闭游标
end;
END PROC_STU1_1;
二.隐式游标
1.使用演示
create or replace PROCEDURE PROC_STU4 AS
BEGIN
--隐式游标使用
update student set stuname='张燕广' where stuno='1104';
--如果更新没有匹配则插入一条新记录
if SQL%NOTFOUND then
insert into student(STUNO,STUNAME,AGE,GENDER)
values('1104','张燕广',18,'男');
end if;
END PROC_STU4;
2.说明
所有的SQL语句在上下文区内部都是可执行的,因为都有一个游标指向上下文区,此游标就是
SQL游标,与现实游标不同的是,SQL游标在PL/SQL中不需要打开和关闭,而是在执行UPDATE、
DELETE是自动打开和关闭。
上面例子中就是通过SQL%NOTFOUND游标属性判断UPDATE语句的执行结果决定是否需要插入新记录。 参考技术A 简单的说。。就是oracle不允许定义数组,
查找出来的数据是一个大集合的话就需要使用游标进行遍历打印本回答被提问者和网友采纳
sigaddset 是做啥用的?
【中文标题】sigaddset 是做啥用的?【英文标题】:What is sigaddset used for?sigaddset 是做什么用的? 【发布时间】:2014-12-01 11:37:41 【问题描述】:我有这段代码,我使用 sigaddset 和 sigaction。但是,如果我评论 segaddset 结果是一样的
struct sigaction act;
act.sa_handler = process_alarm;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
//sigaddset(&act.sa_mask, SIGINT);
sigaction(SIGALRM, &act, NULL);
for(;;)
alarm(3);
pause();
为什么我需要使用它?
【问题讨论】:
您在运行程序时是否尝试按CTRL + C
并注释掉sigaddset()
?
@SouravGhosh 是的,但正如在其他答案中指出的那样,警报处理程序会快速运行以注意到其影响。在处理程序中添加sleep(10)
,我可以看到区别:)
【参考方案1】:
你在这里做两件事:
填充sigset_t
。 sigset_t 只是信号值的集合,用于各种系统调用。你可以:
为信号处理程序设置信号掩码。当您通过调用 sigaction() 设置信号处理程序时,您可以通过操作 struct sigaction
的 sigset_t sa_mask
成员来做到这一点。
信号处理程序的信号掩码意味着当信号处理程序正在执行时,掩码中的信号将被阻塞 - 即,只要它们被阻塞,这些信号就不会被处理。当信号处理程序完成后,信号输入将被解除阻塞。 被阻塞的信号不会“丢失”,它将在该特定信号再次被解除阻塞时处理。
sigaddset(&act.sa_mask, SIGINT);
表示当SIGALRM
处理程序的代码正在运行时,不会出现 SIGINT 信号。
另一方面,如果您注释掉sigaddset(&act.sa_mask, SIGINT);
,您将只剩下一个使用sigemptyset(&act.sa_mask);
创建的信号的空列表。因此,在 SIGALRM 处理程序函数运行时发生的任何信号都可能抢占该处理程序并为该其他信号执行信号处理程序。
对于 SIGINT,您通常不会注意到与手动测试有任何区别 - 您不太可能在您的 SIGALRM 处理程序正在运行时准确地按下 CTRL-C,并且您的 SIGALRM 处理程序可能运行得足够快,以至于您不会注意到如果SIGINT 稍有延迟。
【讨论】:
【参考方案2】:信号集通过sigset_t
类型进行操作。有几种操作可用于信号集:
sigemptyset
创建一个空集S,S=∅
通过sigaddset
将信号s添加到集合S中,S=S∪s
通过sigdelset
,S=S\s从集合中删除信号s
通过sigfillset
创建所有可能信号的集合。
test is a signal s is in a given set S via sigismember
, s∈S?
这样的集合用在不同的地方:设置新的进程信号掩码、信号处理期间的阻塞集合、请求待处理信号的集合等。
如果要捕获不同的信号,可能看起来某些捕获函数不能被其他函数中断,因此您可以在给定信号的传递过程中添加一组要阻塞的信号。您实际上决定(当未注释时)在 SIGALRM 交付期间阻止 SIGINT。因此,您只能通过在处理程序执行期间发送 SIGINT 来观察这一点;这很难实现。
一个重要的例子?
假设 SIGUSR1 的处理程序修改给定的数据结构,而 SIGUSR2 的处理程序使用相同的数据结构。使两个处理程序不并发非常重要,一个可以在另一个之后运行,但您可能不希望在另一个交付期间被一个中断。您的代码是自并发的,也就是说即使在只有一个线程的情况下,信号也可以引导您实现并发。
【讨论】:
【参考方案3】:sigaddset 用于将相应的信号掩码添加到该 sigset_t 变量。
在 sigaction 中,它不是必需的。当您使用 sigprocmask 时,您可以使用它来阻止我们在该变量中提到的信号。
【讨论】:
以上是关于oracle 游标是做啥用的的主要内容,如果未能解决你的问题,请参考以下文章
maven.multiModuleProjectDirectory 是做啥用的?
cursor.setNotificationUri() 是做啥用的?