ORACLE PL/SQL:函数和可选参数,如何?
我正在寻找创建一个函数的最佳方法,该函数可以不接受任何参数并返回所有结果,但也可以接受参数并返回这些结果。
我在工作中一直在处理的标准是这样的:
FUNCTION get_records (
i_code IN records.code%type := NULL,
i_type IN records.type%type := NULL
) RETURN results
问题是我也想返回具有 NULL 类型的记录,并使用:
WHERE type = nvl(i_type, type)
它只返回具有实际类型的记录,而不是空记录。明显的原因。我只是想知道是否有一种标准方法可以在我们使用的所有功能中实现这一点。巧合的是,如果我提供一个参数...我不想要该字段的 NULL 值。
I'm looking for the optimal way to create a function that can accept no parameters and return all results, but also accepts parameters and return those results.
The standard I've been dealing with at my job is this:
FUNCTION get_records (
i_code IN records.code%type := NULL,
i_type IN records.type%type := NULL
) RETURN results
The problem is that I want to return records that have a type of NULL as well, and using:
WHERE type = nvl(i_type, type)
It only returns records with actual types and not the null records.. for obvious reasons. I was just wondering if there is a standard way of doing this that could be implemented across all functions we use. Coincidentally, if I provide a parameter... I don't want the NULL values of that field.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为什么不简单地添加这种
方式,当传入的参数为空时,它会查找所有内容(包括空值)或指定的值。现在,如果您只想要 null...
示例(将值从 null 更改为 5,您将看到输出)
而 :n = 6
结果将是
(删除了新帖子,误读了参数)
但我喜欢这种新方法,并且避免 NVL
如果您不反对动态 sql
http://www.oracle.com/technetwork/issue-archive/2009/09-jul/o49asktom-090487.html
why not simply what you have with the addition of
that way, when the passed in param is null it looks for everything (including nulls) or the specified value. Now, if you just want the nulls...
example (change the value from null to 5 and you will see the output)
Whereas :n = 6
the results will be
(deleted a new post, misread a param)
But I like the new approach and avoiding the NVL
here's a nifty way to do it if you are not adverse to dynamic sql
http://www.oracle.com/technetwork/issue-archive/2009/09-jul/o49asktom-090487.html
解决此问题的标准方法是重载该函数,而不是使用默认值:
注意:如果您还需要一个版本
i_type
本身,那么如果它具有与以下版本相同的基础类型,您可能会遇到麻烦i_code
- 在这种情况下,您需要为该函数使用不同的名称。The standard way to solve this issue is to overload the function, instead of using default values:
Note: If you also need a version
i_type
by itself, you might have trouble if it has the same underlying type asi_code
- in which case you'd need to use a different name for the function.我突然想到,我猜想使用
DEFAULT
关键字就可以达到目的,不是吗? (以下链接将提供更多详细信息。)使用 DEFAULT 关键字。
编辑 #1
如果我正确理解问题,您希望在
i_type
参数为 NULL 时返回所有记录。在没有更多细节的情况下,我的猜测如下。尽管函数体在下面进行了注释,但这就是我对所提供的信息所能做的全部。
编辑 #2
我对 Oracle 有点生疏,所以我查阅了下面链接的一些文档:
Oracle/PLSQL:NVL 函数
正如我所读到的,您最好在
SELECT< 中使用
NVL
函数/code> 指令,而不是您的WHERE
子句。最后,你的问题到底是什么?你能说得一清二楚吗?
Right off the top of my head, I would guess the use of the
DEFAULT
keyword would do the trick, doesn't it? (The following link will give some further details.)Using the DEFAULT keyword.
EDIT #1
If I understand the question correctly, you want to return all of the records when the
i_type
parameter is NULL. In absence of further details, my guess would be the following.That is all I can do with the information provided, although the function body is commented below.
EDIT #2
I am a bit rusty from Oracle, so I consulted some documentation as linked below:
Oracle/PLSQL: NVL Function
As I have read it, you had better use the
NVL
function within yourSELECT
instruction, and not yourWHERE
clause.In the end, what is your question exactly? Could you make it crystal clear?
重申我对这个问题的理解:您不能将
NULL
的默认值表示“返回所有记录”,因为当前的预期行为是它将仅返回值为实际上是NULL。一种可能性是添加与每个查找参数相对应的布尔参数,该参数指示是否应该实际使用它来过滤结果。这样做的一个潜在问题是调用者可能会指定查找值但无法将标志设置为 true,从而产生意外结果。如果该标志对于
NULL
以外的任何查找值都为 false,则可以在运行时通过引发异常来防止这种情况。另一种可能性是为每个查找列定义一个域外值——例如,如果为参数传递字符串“ANY”,则它不会过滤该列上的值。只要您能为每列找到一个有价值的哨兵值,这应该可以正常工作。我建议将哨兵值声明为某个包中的常量,以便对该函数的调用看起来像
get_records( PKG.ALL_CODES, 'type1' )
。To reiterate my understanding of the issue: You can't take the default value of
NULL
to mean "return all records", because the current expected behavior is that it will return only those records where the value is actually NULL.One possibility is to add a boolean parameter corresponding to each lookup parameter, which indicates whether it should actually be used to filter results. A potential issue with this is that a caller might specify a lookup value but fail to set the flag to true, producing unexpected results. You can guard against this at runtime by raising an exception if the flag is false for any lookup value other than
NULL
.Another possibility is to define an out-of-domain value for each lookup column -- e.g. if the string 'ANY' is passed for the parameter, it will not filter values on that column. This should work fine as long as you can find a worthwhile sentry value for each column. I'd suggest declaring the sentry values as constants in some package, so that calls to the function could look like
get_records( PKG.ALL_CODES, 'type1' )
.我一直在使用以下 hack(假设 p_product 是可选的过程输入):
where t.product =decode(p_product, null, t.product, p_product)
这将创建 'where 1=1'不传入产品的场景,否则使用该产品。一个潜在的主要缺点是,无论参数如何,它都会解析为相同的执行计划。
I have been using the following hack (assuming p_product is an optional procedure input):
where t.product = decode(p_product, null, t.product, p_product)
This will create 'where 1=1' scenario when the product is not passed in, and use the product otherwise. One potentially major drawback is that this parses to the same execution plan regardless of parameters.