PL/SQL:将词法参数传递给存储过程

Posted

技术标签:

【中文标题】PL/SQL:将词法参数传递给存储过程【英文标题】:PL/SQL: Passing lexical parameter to a stored procedure 【发布时间】:2011-04-20 05:32:00 【问题描述】:

我想将整个 sql 查询作为词法参数传递给存储过程,然后执行它。有什么建议吗?

【问题讨论】:

“执行”是什么意思?查询旨在返回结果 - 您需要定义希望存储过程对结果执行的操作。 嗨 Jeffrey,我想做的是在运行时将查询提供给存储过程,例如,我想执行插入操作,当我执行该过程时,我将在运行时提供插入查询。跨度> 查询是否总是返回相同的列和数据类型集? 不,因为如果是这样,就不需要传递整个查询。 不清楚你需要这个程序做什么。 【参考方案1】:

你可以试试这个:

create or replace procedure my_proc(pstring IN varchar2)
is

begin

  if length(pstring)>0 then

     EXECUTE IMMEDIATE pstring;

  end if;

end my_proc;

这里是关于动态 plsql 的官方 oracle 文档:http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/dynamic.htm#CHDGJEGD

【讨论】:

谢谢 Alex,这真的很有帮助。 非常、非常、非常确定您没有其他方法可以做到这一点?执行未知的 SQL 可能非常危险,如果攻击者遇到这种情况,基本上可以对您的数据库做任何事情......【参考方案2】:

不确定您所说的“词法”参数是什么意思,但您可以将 SQL 查询作为 VARCHAR2 传递,然后使用 EXECUTE IMMEDIATE 执行它。

【讨论】:

感谢您的回复,我正在这样做。按原样创建或替换过程 testproc(str varchar2(1000)) 开始执行立即 (str);结尾;这是正确的方法还是我遗漏了什么? 省略“(1000)”,因为您没有指定 IN 参数的长度。【参考方案3】:

你试图做的几乎肯定是错误的方法。

Execute Immediate 应谨慎使用,因为它可以 a) 带来安全风险 b) 当许多不同的 SQL 语句以这种方式运行时会对性能造成负面影响。

但是,请参阅 here 如何使用 execute immediate 插入记录。请注意,必须使用绑定变量。

【讨论】:

【参考方案4】:

如果您想运行 查询(而不是 DML [插入、更新、删除] 或 PL/SQL 代码块),您可以执行以下操作:

function get_dataset (p_sql_query in varchar2) return sys_refcursor
as
  l_returnvalue sys_refcursor;
begin

  open l_returnvalue for p_sql_query;

  return l_returnvalue;

end get_dataset;

返回值是一个“弱类型”的 REF CURSOR。

调用程序(无论是 Java、.NET、PL/SQL 等)必须随后处理函数结果并关闭游标。

【讨论】:

感谢 ObiWanKenobi,这很有用。

以上是关于PL/SQL:将词法参数传递给存储过程的主要内容,如果未能解决你的问题,请参考以下文章

pl/sql 循环遍历表并将行的每个条目传递给存储过程

将值列表作为输入参数传递给 PL/SQL 过程

将 BLOB/CLOB 作为参数传递给 PL/SQL 函数

将参数传递给C#中的存储过程

将xml作为输入参数传递给存储过程

VBScript:将具有空值的参数传递给存储过程?