如何查找 Oracle PL/SQL 游标中的记录数?
这是我的光标:
CURSOR C1 IS SELECT * FROM MY_TABLE WHERE SALARY < 50000 FOR UPDATE;
我立即打开光标,以便在程序期间锁定这些记录。
我想在存在 << 的情况下提出应用程序错误我的光标中有 2 条记录。使用 C1%ROWCOUNT 属性会失败,因为它只计算迄今为止已获取的数量。
该用例的最佳模式是什么?我是否需要创建一个虚拟 MY_TABLE%ROWTYPE 变量,然后循环游标以将它们取出并保持计数,或者是否有更简单的方法?如果这是这样做的方法,那么获取游标中的所有行会隐式关闭它,从而解锁这些行,或者即使我已经获取了所有行,它也会保持打开状态直到我显式关闭它吗?
我需要确保光标保持打开状态以执行超出此计数的各种其他任务。
Here's my cursor:
CURSOR C1 IS SELECT * FROM MY_TABLE WHERE SALARY < 50000 FOR UPDATE;
I immediately open the cursor in order to lock these records for the duration of my procedure.
I want to raise an application error in the event that there are < 2 records in my cursor. Using the C1%ROWCOUNT property fails because it only counts the number which have been fetched thus far.
What is the best pattern for this use case? Do I need to create a dummy MY_TABLE%ROWTYPE variable and then loop through the cursor to fetch them out and keep a count, or is there a simpler way? If this is the way to do it, will fetching all rows in my cursor implicitly close it, thus unlocking those rows, or will it stay open until I explicitly close it even if I've fetched them all?
I need to make sure the cursor stays open for a variety of other tasks beyond this count.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
注意:我刚刚重读了你的问题..如果只有 1 条记录,你想失败..
我稍后会发布新的更新..
让我们从这里开始..
来自 Oracle® Database PL/SQL 用户指南和参考
10g 版本 2 (10.2)
零件号 B14261-01
参考
所以您无需担心记录解锁。
所以试试这个..
替代答案
我从后面读到你的答案,并认为如果有超过 1 行,你想退出。不完全是一行。所以这是我之前的答案。
2 种简单方法仅检查 1 条记录。
选项 1 - 显式获取
我希望您明白这一点。
选项 2 - 异常捕获
另外
请记住:使用显式游标..您可以从游标记录而不是原始表中%TYPE您的变量。
当查询中有联接时,这尤其有用。
另外,请记住,您可以使用 type 语句更新表中的行
,但只有在您没有“获取”第二行时,这才有效。.
有关游标 FOR 循环的更多信息..尝试
此处
NB: i just reread you question.. and you want to fail if there is ONLY 1 record..
i'll post a new update in a moment..
lets start here..
From Oracle® Database PL/SQL User's Guide and Reference
10g Release 2 (10.2)
Part Number B14261-01
reference
so you do not need to worry about the records unlocking.
so try this..
ALTERNATE ANSWER
I read you answer backwards to start and thought you wanted to exit if there was MORE then 1 row.. not exactly one.. so here is my previous answer.
2 simple ways to check for ONLY 1 record.
Option 1 - Explicit Fetchs
I hope you get the idea.
Option 2 - Exception Catching
Additionally
Remember: with an explicit cursor.. you can %TYPE your variable off the cursor record rather then the original table.
this is especially useful when you have joins in your query.
Also, rememebr you can update the rows in the table with an
type statement, but I that will only work if you haven't 'fetched' the 2nd row..
for some more information about cursor FOR loops.. try
Here
如果您希望在返回超过 1 行时失败,请尝试以下操作:
If you're looking to fail whenver you have more than 1 row returned, try this:
锁将在事务持续时间内存在(即直到您执行提交或回滚),无论您何时(或是否)关闭游标。
我会选择
在打开游标(锁定行)和选择计数之间,有人将工资低于 50000 的一行或多行插入到表中的可能性很小。在这种情况下,应用程序错误将被引发,但游标只会处理打开游标时出现的行。如果这是一个担心,最后对 c_1%rowcount 进行另一次检查,如果遇到该问题,则需要回滚到保存点。
The locks will be present for the duration of the transaction (ie until you do a commit or rollback) irrespective of when (or whether) you close the cursor.
I'd go for
There's a very small chance that, between the time the cursor is opened (locking rows) and the select count, someone inserts one or more rows into the table with a salary under 50000. In that case the application error would be raised but the cursor would only process the rows present when the cursor was opened. If that is a worry, at the end do another check on c_1%rowcount and, if that problem was experienced, you'd need to rollback to a savepoint.
在遍历游标之前创建一个保存点,然后在发现有 << 时使用部分回滚。返回 2 条记录。
Create a savepoint before you iterate through the cursor and then use a partial rollback when you find there are < 2 records returned.
您可以启动事务并检查是否 SELECT COUNT(*) MY_TABLE WHERE SALARY < 50000 大于 1。
You can start transaction and check if SELECT COUNT(*) MY_TABLE WHERE SALARY < 50000 greater than 1.