显式游标
当查询返回结果超过一行时 就需要一个显式游标 此时用户不能使用select into语句 PL/SQL管理隐式游标 当查询开始时隐式游标打开 查询结束时隐式游标自动关闭 显式游标在PL/SQL块的声明部分声明 在执行部分或异常处理部分打开 取出数据 关闭
使用游标
这里要做一个声明 我们所说的游标通常是指显式游标 因此从现在起没有特别指明的情况 我们所说的游标都是指显式游标 要在程序中使用游标 必须首先声明游标
声明游标
语法
CURSOR cursor_name IS select_statement;
在PL/SQL中游标名是一个未声明变量 不能给游标名赋值或用于表达式中
例
DELCARE CURSOR C_EMP IS SELECT empno ename salary FROM emp WHERE salary> ORDER BY ename; BEGIN
在游标定义中SELECT语句中不一定非要表可以是视图 也可以从多个表或视图中选择的列 甚至可以使用来选择所有的列
打开游标
使用游标中的值之前应该首先打开游标 打开游标初始化查询处理 打开游标的语法是
OPEN cursor_name
cursor_name是在声明部分定义的游标名
例
OPEN C_EMP; 关闭游标
语法
CLOSE cursor_name
例
CLOSE C_EMP; 从游标提取数据 从游标得到一行数据使用FETCH命令 每一次提取数据后 游标都指向结果集的下一行 语法如下
FETCH cursor_name INTO variable[ variable ]
对于SELECT定义的游标的每一列 FETCH变量列表都应该有一个变量与之相对应 变量的类型也要相同
例
SET SERVERIUTPUT ON DECLARE v_ename EMP ENAME%TYPE; v_salary EMP SALARY%TYPE; CURSOR c_emp IS SELECT ename salary FROM emp; BEGIN OPEN c_emp; FETCH c_emp INTO v_ename v_salary; DBMS_OUTPUT PUT_LINE( Salary of Employee || v_ename || is || v_salary); FETCH c_emp INTO v_ename v_salary; DBMS_OUTPUT PUT_LINE( Salary of Employee || v_ename || is || v_salary); FETCH c_emp INTO v_ename v_salary; DBMS_OUTPUT PUT_LINE( Salary of Employee || v_ename || is || v_salary); CLOSE c_emp; END
这段代码无疑是非常麻烦的 如果有多行返回结果 可以使用循环并用游标属性为结束循环的条件 以这种方式提取数据 程序的可读性和简洁性都大为提高 下面我们使用循环重新写上面的程序
SET SERVERIUTPUT ON DECLARE v_ename EMP ENAME%TYPE; v_salary EMP SALARY%TYPE; CURSOR c_emp IS SELECT ename salary FROM emp; BEGIN OPEN c_emp; LOOP FETCH c_emp INTO v_ename v_salary; EXIT WHEN c_emp%NOTFOUND; DBMS_OUTPUT PUT_LINE( Salary of Employee || v_ename || is || v_salary); END
记录变量
定义一个记录变量使用TYPE命令和%ROWTYPE 关于%ROWsTYPE的更多信息请参阅相关资料
记录变量用于从游标中提取数据行 当游标选择很多列的时候 那么使用记录比为每列声明一个变量要方便得多
当在表上使用%ROWTYPE并将从游标中取出的值放入记录中时 如果要选择表中所有列 那么在SELECT子句中使用比将所有列名列出来要得多
例
SET SERVERIUTPUT ON DECLARE R_emp EMP%ROWTYPE; CURSOR c_emp IS SELECT FROM emp; BEGIN OPEN c_emp; LOOP FETCH c_emp INTO r_emp; EXIT WHEN c_emp%NOTFOUND; DBMS_OUT PUT PUT_LINE( Salary of Employee ||r_emp ename|| is || r_emp salary); END LOOP; CLOSE c_emp; END;
%ROWTYPE也可以用游标名来定义 这样的话就必须要首先声明游标
SET SERVERIUTPUT ON DECLARE CURSOR c_emp IS SELECT ename salary FROM emp; R_emp c_emp%ROWTYPE; BEGIN OPEN c_emp; LOOP FETCH c_emp INTO r_emp; EXIT WHEN c_emp%NOTFOUND; DBMS_OUT PUT PUT_LINE( Salary of Employee ||r_emp ename|| is || r_emp salary); END LOOP; CLOSE c_emp; END;
带参数的游标
与存储过程和函数相似 可以将参数传递给游标并在查询中使用 这对于处理在某种条件下打开游标的情况非常有用 它的语法如下
CURSOR cursor_name[(parameter[ parameter] )] IS select_statement;
定义参数的语法如下
Parameter_name [IN] data_type[{:=|DEFAULT} value]
与存储过程不同的是 游标只能接受传递的值 而不能返回值 参数只定义数据类型 没有大小
另外可以给参数设定一个缺省值 当没有参数值传递给游标时 就使用缺省值 游标中定义的参数只是一个占位符 在别处引用该参数不一定可靠
在打开游标时给参数赋值 语法如下
OPEN cursor_name[value[ value] ];
参数值可以是文字或变量
例
DECALRE CURSOR c_dept IS SELECT FROM dept ORDER BY deptno; CURSOR c_emp (p_dept VARACHAR ) IS SELECT ename salary FROM emp WHERE deptno=p_dept ORDER BY ename r_dept DEPT%ROWTYPE; v_ename EMP ENAME%TYPE; v_salary EMP SALARY%TYPE; v_tot_salary EMP SALARY%TYPE; BEGIN OPEN c_dept; LOOP FETCH c_dept INTO r_dept; EXIT WHEN c_dept%NOTFOUND; DBMS_OUTPUT PUT_LINE ( Department: || r_dept deptno|| ||r_dept dname); v_tot_salary:= ; OPEN c_emp(r_dept deptno); LOOP FETCH c_emp INTO v_ename v_salary; EXIT WHEN c_emp%NOTFOUND; DBMS_OUTPUT PUT_LINE ( Name: || v_ename|| salary: ||v_salary); v_tot_salary:=v_tot_salary+v_salary; END LOOP; CLOSE c_emp; DBMS_OUTPUT PUT_LINE ( Toltal Salary for dept: || v_tot_salary); END LOOP; CLOSE c_dept; END;
游标FOR循环
在大多数时候我们在设计程序的时候都遵循下面的步骤
打开游标
开始循环
从游标中取值
那一行被返回
处理
关闭循环
关闭游标
可以简单的把这一类代码称为游标用于循环 但还有一种循环与这种类型不相同 这就是FOR循环 用于FOR循环的游标按照正常的声明方式声明 它的优点在于不需要显式的打开 关闭 取数据 测试数据的存在 定义存放数据的变量等等 游标FOR循环的语法如下
FOR record_name IN (corsor_name[(parameter[ parameter] )] | (query_difinition) LOOP statements END LOOP;
下面我们用for循环重写上面的例子
DECALRE CURSOR c_dept IS SELECT deptno dname FROM dept ORDER BY deptno; CURSOR c_emp (p_dept VARACHAR ) IS SELECT ename salary FROM emp WHERE deptno=p_dept ORDER BY ename v_tot_salary EMP SALARY%TYPE; BEGIN FOR r_dept IN c_dept LOOP DBMS_OUTPUT PUT_LINE ( Department: || r_dept deptno|| ||r_dept dname); v_tot_salary:= ; FOR r_emp IN c_emp(r_dept deptno) LOOP DBMS_OUTPUT PUT_LINE ( Name: || v_ename || salary: || v_salary); v_tot_salary:=v_tot_salary+v_salary; END LOOP; DBMS_OUTPUT PUT_LINE ( Toltal Salary for dept: || v_tot_salary); END LOOP; END;
在游标FOR循环中使用查询
在游标FOR循环中可以定义查询 由于没有显式声明所以游标没有名字 记录名通过游标查询来定义
DECALRE v_tot_salary EMP SALARY%TYPE; BEGIN FOR r_dept IN (SELECT deptno dname FROM dept ORDER BY deptno) LOOP DBMS_OUTPUT PUT_LINE( Department: || r_dept deptno|| ||r_dept dname); v_tot_salary:= ; FOR r_emp IN (SELECT ename salaryFROM empWHERE deptno=p_deptORDER BY ename) LOOP DBMS_OUTPUT PUT_LINE( Name: || v_ename|| salary: ||v_salary); v_tot_salary:=v_tot_salary+v_salary; END LOOP; DBMS_OUTPUT PUT_LINE( Toltal Salary for dept: || v_tot_salary); END LOOP; END;
游标中的子查询
语法如下
CURSOR C IS SELECT FROM emp WHERE deptno NOT IN (SELECT deptno FROM dept WHERE dname!= ACCOUNTING );
可以看出与SQL中的子查询没有什么区别
游标中的更新和删除
在PL/SQL中依然可以使用UPDATE和DELETE语句更新或删除数据行 显式游标只有在需要获得多行数据的情况下使用 PL/SQL提供了仅仅使用游标就可以执行删除或更新记录的方法
UPDATE或DELETE语句中的WHERE CURRENT OF子串专门处理要执行UPDATE或DELETE *** 作的表中取出的最近的数据 要使用这个方法 在声明游标时必须使用FOR UPDATE子串 当对话使用FOR UPDATE子串打开一个游标时 所有返回集中的数据行都将处于行级(ROW LEVEL)独占式锁定 其他对象只能查询这些数据行 不能进行UPDATE DELETE或SELECT FOR UPDATE *** 作
语法
FOR UPDATE [OF [schema ]lumn[ [schema ]lumn] [nowait]
在多表查询中 使用OF子句来锁定特定的表 如果忽略了OF子句 那么所有表中选择的数据行都将被锁定 如果这些数据行已经被其他会话锁定 那么正常情况下ORACLE将等待 直到数据行解锁
在UPDATE和DELETE中使用WHERE CURRENT OF子串的语法如下
WHERE{CURRENT OF cursor_name|search_condition}
例
DELCARE CURSOR c IS SELECT empno salary FROM emp WHERE m IS NULL FOR UPDATE OF m; v_m NUMBER( ); BEGIN FOR r IN c LOOP IF r salary< THEN v_m:=r salary ; ELSEIF r salary< THEN v_m:=r salary ; ELSEIF r salary< THEN v_m:=r salary ; ELSE v_m:=r salary ; END IF; UPDATE emp; SET m=v_m WHERE CURRENT OF c l; END LOOP; END
lishixinzhi/Article/program/Oracle/201311/16865
游标(cursor)是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。每个游标区都有一个名字,用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理。游标提供了一种对从表中检索出的数据进行 *** 作的灵活手段。\x0d\使用游标的基本步骤: \x0d\1、声明游标。把游标与T-SQL语句的结果集联系起来。 \x0d\2、打开游标。 \x0d\3、使用游标 *** 作数据。 \x0d\4、关闭游标。\x0d\功能:\x0d\1、游标提供了一种对从表中检索出的数据进行 *** 作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。\x0d\2、游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。\x0d\3、游标把作为面向集合的数据库管理系统和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。\x0d\种类:\x0d\1、Transact_SQL游标\x0d\Transact_SQL游标是由DECLARECURSOR语法定义、主要用在Transact_SQL脚本、存储过程和触发器中。Transact_SQL游标主要用在服务器上,由从客户端发送给服务器的Transact_SQL语句或是批处理、存储过程、触发器中的Transact_SQL进行管理。Transact_SQL游标不支持提取数据块或多行数据。\x0d\2、API游标\x0d\API游标支持在OLEDB,ODBC以及DB_library中使用游标函数,主要用在服务器上。每一次客户端应用程序调用API游标函数,MSSQLSEVER的OLEDB提供者、ODBC驱动器或DB_library的动态链接库(DLL)都会将这些客户请求传送给服务器以对API游标进行处理。\x0d\3、客户游标\x0d\客户游标主要是当在客户机上缓存结果集时才使用。在客户游标中,有一个缺省的结果集被用来在客户机上缓存整个结果集。客户游标仅支持静态游标而非动态游标。由于服务器游标并不支持所有的Transact-SQL语句或批处理,所以客户游标常常仅被用作服务器游标的辅助。因为在一般情况下,服务器游标能支持绝大多数的游标 *** 作。由于API游标和Transact-SQL游标使用在服务器端,所以被称为服务器游标,也被称为后台游标,而客户端游标被称为前台游标。
1、首先打开SQL Server Management管理工具,使用sql语句创建一张测试表。
2、在测试表中,插入3条测试数据。
3、使用一条语句批量修改整个表的数据。
4、使用一条语句批量修改指定条数的记录。
5、使用一条语句批量修改这三条数据(按条件修改值)。
6、使用一条语句批量修改数据,使用where和case when。
在数据库中,游标提供了一种对从表中检索出的数据进行 *** 作的灵活手段。就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。
游标总是与一条SQL
选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。
游标关于数据库中的 *** 作会对整个行集产生影响。由SELECT语句返回的行集包括所有满足该语句WHERE子句中条件的行。由语句所返回的这一完整的行集被称为结果集。
应用程序,特别是交互式联机应用程序,并不总能将整个结果集作为一个单元来有效地处理。这些应用程序需要一种机制以便每次处理一行或一部分行。游标就是提供这种机制的结果集扩展。
扩展资料:
游标通过以下方式扩展结果处理:
1允许定位在结果集的特定行。
2从结果集的当前位置检索一行或多行。
3支持对结果集中当前位置的行进行数据修改。
4为由其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性支持。
5提供脚本、存储过程和触发器中使用的访问结果集中的数据的Transact-SQL语句。
游标(cursor)是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。每个游标区都有一个名字,用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理。
create proc cursorTest
@_id int=0,
@_name varchar(50)=''
as--创建游标
declare @cursor cursor--设定游标欲 *** 作的数据集
set @cursor=cursor for
select _id,_name from users
open @cursor--打开游标
fetch next from @cursor into @_id,@_name--移动游标指向到第一条数据,提取第一条数据存放在变量中
while(@@fetch_status=0)begin--如果上一次 *** 作成功则继续循环
print @_name-- *** 作提出的数据
fetch next from @cursor into @_id,@_name--继续提下一行
end
close @cursor--关闭游标
deallocate @cursor--删除游标
VB可通过结构化查询语言(SQL)访问数据库。
下面帮你写一个简单的过程,将学号以参数传给该过程:
Private Sub editmark(num as Integer)
'声明一个记录集
Dim rs As New ADODBRecordset
'定义一个SQL查询串
SQLStr = "select from student where id=" & num
'执行查询
rsOpen SQLStr, Conn, 3, 2
If Not rsEOF Then
rs("mark")=rs("mark")-10
end if
'更新数据库
rsupdate
End Sub
--------------------------------------------------------------
补充:
1、对于Conn提问者肯定明白,因为提问者已经说明连接部分可以忽略;
2、对于rs("mark")=rs("mark")-10 是可行的,因为通过过程参数的传递记录已经定位在某条记录上,还考虑什么转移;
3、我们回答提问者的问题应尽量简单可行,说明问题即可,无需长篇大论让提问者一头雾水,长篇大论就是“敬业”吗?
--------------------------------------------------------------
最后补充:
没有关系,我们是在讨论问题嘛!
其实,对于“vb *** 作数据库”我相信不是我们在这里举一个简单的例子能说透的。我只是想通过这个简单的例子(越简单越易让提问者搞懂),告诉提问者用SQL可以访问并 *** 作数据库,至于具体许多细节需要提问者熟悉一下SQL和VB提供的ADO,我想这也是提问者的真实意图。
另外,关于rs("mark")=rs("mark")-10在这个例子中肯定是可行的,因为学生的id肯定是唯一的(应该是数据表student的主键),不会有重复的id。
SQL中的select语句,其查询的结果,是返回满足某个条件的属性列的集合,如果我们要逐项使用返回的数据,比如说,想要把c哦11ege表的所有学院名字取出,逐项存放到某窗口的某的列表项中,仅仅用SQL所提供的增、删、改、查 *** 作,是实现不了的,这就需要用到数据库游标,使用数据库游标来实现逐项选取select语句返回的属性列
以上就是关于快速掌握Oracle数据库游标的使用方法全部的内容,包括:快速掌握Oracle数据库游标的使用方法、什么是游标使用游标的基本步骤是什么、怎样修改数据库中的数据等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)