当结果可能为空时,如何选择 PL/SQL 中的变量?
有没有办法只运行一次查询来选择变量,考虑到查询可能不返回任何内容,那么在这种情况下变量应该为空。
目前,我无法直接select into
变量,因为如果查询不返回任何内容,PL/SQL 会抱怨变量未设置。我只能运行查询两次,第一次执行计数,如果计数为零,则将变量设置为 null,如果计数为 1,则选择变量。
所以代码应该是这样的:
v_column my_table.column%TYPE;
v_counter number;
select count(column) into v_counter from my_table where ...;
if (v_counter = 0) then
v_column := null;
elsif (v_counter = 1) then
select column into v_column from my_table where ...;
end if;
谢谢。
更新: 我没有使用异常的原因是在分配v_column
之后我仍然有一些以下逻辑,并且我必须在异常部分使用goto
跳回以下内容代码。我对goto
行有点犹豫。
Is there a way in to just run a query once to select into a variable, considering that the query might return nothing, then in that case the variable should be null.
Currently, I can't do a select into
a variable directly, since if the query returns nothing, the PL/SQL would complain variable not getting set. I can only run the query twice, with the first one do the count and if the count is zero, set the variable to null, and if the count is 1, select into the variable.
So the code would be like:
v_column my_table.column%TYPE;
v_counter number;
select count(column) into v_counter from my_table where ...;
if (v_counter = 0) then
v_column := null;
elsif (v_counter = 1) then
select column into v_column from my_table where ...;
end if;
thanks.
Update:
The reason I didn't use exception is I still have some following logic after assigning the v_column
, and I have to use goto
in the exception section to jump back to the following code. I'm kind of hesitate of goto
lines.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您只需将变量设置为
NULL
即可处理NO_DATA_FOUND
异常。这样,只需要一次查询。You can simply handle the
NO_DATA_FOUND
exception by setting your variable toNULL
. This way, only one query is required.我知道这是一个旧线程,但我仍然认为值得回答它。
使用示例:
I know it's an old thread, but I still think it's worth to answer it.
Example of use:
使用 MAX 怎么样?
这样,如果没有找到数据,则变量设置为 NULL,否则设置为最大值。
由于您期望 0 或 1 值,因此 MAX 应该可以使用。
What about using MAX?
That way if no data is found the variable is set to NULL, otherwise the maximum value.
Since you expect either 0 or 1 value, MAX should be OK to use.
我最喜欢使用 游标 FOR LOOP 语句方法来做到这一点。
它比使用显式游标更安全,因为您不需要记住关闭它,因此您不能“泄漏”游标。
您不需要“进入”变量,不需要“FETCH”,不需要捕获和处理“NO DATA FOUND”异常。
尝试一下,你永远不会回去。
Using an Cursor FOR LOOP Statement is my favourite way to do this.
It is safer than using an explicit cursor, because you don't need to remember to close it, so you can't "leak" cursors.
You don't need "into" variables, you don't need to "FETCH", you don't need to catch and handle "NO DATA FOUND" exceptions.
Try it, you'll never go back.
从上面的所有答案来看,Björn 的答案似乎是最优雅和简短的。我个人多次使用过这种方法。 MAX 或 MIN 函数同样可以很好地完成这项工作。完整的 PL/SQL 如下,只需指定 where 子句。
From all the answers above, Björn's answer seems to be the most elegant and short. I personally used this approach many times. MAX or MIN function will do the job equally well. Complete PL/SQL follows, just the where clause should be specified.
我建议使用光标。游标获取始终是单行(除非您使用批量集合),并且游标不会自动抛出 no_data_found 或 Too_many_rows 异常;尽管您可以在打开后检查游标属性以确定是否有一行以及有多少行。
或者,更简单:
I would recommend using a cursor. A cursor fetch is always a single row (unless you use a bulk collection), and cursors do not automatically throw no_data_found or too_many_rows exceptions; although you may inspect the cursor attribute once opened to determine if you have a row and how many.
Or, even more simple:
我使用这种语法是为了灵活性和速度 -
Dual 返回 1 行,rownum 添加 0 或 1 行,max() 组恰好为 1。这对于表中没有行给出 0,对于任何其他行数给出 1。
我扩展了 where 子句以按条件对行进行计数,删除 rownum 以对满足条件的行进行计数,并增加 rownum 以对满足条件的行进行计数直至达到限制。
I use this syntax for flexibility and speed -
Dual returns 1 row, rownum adds 0 or 1 rows, and max() groups to exactly 1. This gives 0 for no rows in a table and 1 for any other number of rows.
I extend the where clause to count rows by condition, remove rownum to count rows meeting a condition, and increase rownum to count rows meeting the condition up to a limit.
COALESCE
将始终返回第一个非空结果。通过这样做,你将得到你想要的计数或 0:COALESCE
will always return the first non-null result. By doing this, you will get the count that you want or 0: