如何在 PLSQL 过程中将字符串值作为参数传递

Posted

技术标签:

【中文标题】如何在 PLSQL 过程中将字符串值作为参数传递【英文标题】:how to pass string values as parameter in PLSQL procedure 【发布时间】:2017-09-25 09:20:00 【问题描述】:

以下是我希望我的过程生成的示例查询

select * 
   from Registration 
  where Loc_ID = 6 
    AND CROP_ID = 163 
    AND REG_NAME = 'Apiro MX';

REG_NAMEvarchar2()

我创建了一个过程,我想在其中执行一个查询,如下所示

query := 'select REG_ID from Registration where loc_id = ' || 
          countryid || ' AND Crop_id = ' || cropid || 
          ' AND Reg_name = '|| ''' || productid || ''' || ';

我在REG_NAME 部分出现错误,它将productid 视为" || productid ||"

你能帮我解答一下这个问题吗?

【问题讨论】:

为什么要使用动态 SQL 进行查询? (如果你有真正的理由,为什么不使用绑定变量?) 我们不能使用动态 sql 来做到这一点吗?如果可以,请您帮我更正该查询。 当然可以,只需转义您正在使用的引号,或者(更多)最好使用绑定变量;但你为什么要?它的效率较低且难以维护。 实际上,到目前为止,我已经在 DB 中做了很多更改,如果我采用其他方式,我需要恢复这些更改并消耗时间。你能帮我更正那个查询吗?因为我已经改变了很多次 【参考方案1】:

你不需要使用动态sql:

CREATE PROCEDURE get_registration (
  i_countryid IN  REGISTRATION.LOC_ID%TYPE,
  i_crop_id   IN  REGISTRATION.CROP_ID%TYPE,
  i_reg_name  IN  REGISTRATION.REG_NAME%TYPE,
  o_cursor    OUT SYS_REFCURSOR
)
AS
BEGIN
  OPEN o_cursor FOR
    SELECT *
    FROM   Registration
    WHERE  Loc_ID   = i_countryid
    AND    CROP_ID  = i_crop_id
    AND    REG_NAME = i_reg_name;
END;
/

如果您确实需要动态 SQL(但是,您几乎总是可以不用):

CREATE PROCEDURE get_registration (
  i_countryid IN  REGISTRATION.LOC_ID%TYPE,
  i_crop_id   IN  REGISTRATION.CROP_ID%TYPE,
  i_reg_name  IN  REGISTRATION.REG_NAME%TYPE,
  o_cursor    OUT SYS_REFCURSOR
)
AS
BEGIN
  OPEN o_cursor
  FOR 'SELECT *
       FROM   Registration
       WHERE  Loc_ID   = :i
       AND    CROP_ID  = :j
       AND    REG_NAME = :k'
  USING i_countryid, i_crop_id, i_reg_name;
END;
/

【讨论】:

如果我想使用动态 sql 做到这一点,有可能吗?你能帮我更正那个查询吗? 原始查询是“正确的”,但是,我可以为您提供替代方案。【参考方案2】:

在 PLSQL 中,您可以通过添加另一个引号来转义引号,因此, 您应该在 productid 周围加上双引号。 尝试类似:

query := 'select REG_ID from Registration where loc_id = ' || 
      countryid || ' AND Crop_id = ' || cropid || 
      ' AND Reg_name = '|| '''' || productid || '''' || ';

或者不要使用动态 SQL 并尝试创建存储过程 (检查说明的链接)。 http://plsql-tutorial.com/plsql-procedures.htm

【讨论】:

这是个坏主意 XKCD - 如果您不使用绑定变量,那么用户可能会做一些意想不到的事情,例如将 productid 传递为 Apiro MX' AND EXISTS( SELECT 1 FROM your_password_table WHERE passwordhash = '123456' ) AND '1' = '1

以上是关于如何在 PLSQL 过程中将字符串值作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Oracle SQL Developer 的存储过程中将表名列表作为参数传递?如何使用 PLSQL VARRAY 或嵌套表?

在存储过程中将输入参数作为值传递

如何将表作为参数传递并使用 plsql 过程填充该表

java字符串数组作为参数传递oracle存储过程

如何在 BLToolkit 中将 DataTable 作为参数传递?

如何在 API 调用中将输入值作为参数传递?