如何创建一个Oracle存储过程,以接受用于馈送IN子句的可变数量的参数值?
这就是我正在努力实现的目标。我不知道如何在PLSQL中声明传递我想要更新的行的主键的变量列表。
FUNCTION EXECUTE_UPDATE
( <parameter_list>
value IN int)
RETURN int IS
BEGIN
[...other statements...]
update table1 set col1 = col1 - value where id in (<parameter_list>)
RETURN SQL%ROWCOUNT ;
END;
此外,我想从C#调用此过程,因此它必须与.NET功能兼容。
谢谢你,罗伯特
8条答案
按热度按时间7xzttuei1#
使用CSV可能是最简单的方法,假设您可以100%确定您的元素本身不会包含字符串。
执行此操作的另一种方法是创建自定义类型作为字符串表,这可能是更可靠的方法。假设您的字符串不超过100个字符,那么您可以:
然后,可以将此类型的变量传递到存储过程中并直接引用它。在你的案例中,大概是这样的:
table()
函数将您的自定义类型转换为具有单个列“COLUMN_VALUE”的表,然后您可以像对待任何其他表一样处理该表(连接也是如此,在本例中是子选择)。这样做的好处是Oracle将为您创建一个构造函数,因此在调用您的存储过程时,您可以简单地编写:
我假设您可以从C#以编程方式构建此命令。
顺便说一句,在我的公司,我们有许多这样的定制类型被定义为字符串、双精度、整型等列表的标准。我们还利用Oracle JPublisher能够直接从这些类型Map到相应的Java对象。我快速地环顾了一下周围,但我没有看到任何与C#直接对应的东西。我只是想提一下,以防Java开发人员遇到这个问题。
gz5pxeao2#
我认为没有直接的方法来创建具有可变数量的参数的过程。然而,如here所述,这个问题有一些,至少是部分解决方案。
1.如果有一些典型的调用类型,过程重载可能会有所帮助。
1.如果参数数量有上限(且其类型也已预先知道),则参数的默认值可能会有所帮助。
1.最好的选择可能是使用游标变量,它们是指向数据库游标的指针。
不幸的是,我没有.NET环境的经验。
des4xlb03#
我找到了马克·A·威廉姆斯的以下文章,我认为这将是对这个帖子的有用补充。本文给出了一个使用关联数组将数组从C#传递到PL/SQL过程的很好的例子(myType类型是myable.row%type index by PLS_INTEGER的表):
Great article by Mark A. Williams
kmb7vmvb4#
为什么不使用一个长参数列表并将值加载到表构造函数中呢?以下是此技巧的SQL/PSM
ibps3vxo5#
只需将变量拆分为逗号分隔的字符串:
注意:Prod用户总规模为:18.8125 MB。
PL/SQL过程已成功完成。
qxgroojn6#
我没有为Oracle这样做过,但是在SQL Server中,您可以使用一个函数将CSV字符串转换为表,然后可以在IN子句中使用它。为Oracle重写这篇文章应该是直截了当的(我认为!)
然后,您可以传入CSV字符串(例如‘0001,0002,0003’)并执行如下操作
mctunoxg7#
AskTom网站上有一篇文章,展示了如何创建一个函数来解析CSV字符串,并以类似于给出的SQL Server示例的方式在语句中使用它。
见Asktom
blpfk2vs8#
为什么它必须是存储过程?您可以通过编程方式构建预准备语句。