【问题标题】:Oracle Stored Procedure not working (where in string)Oracle 存储过程不起作用(在字符串中的位置)
【发布时间】:2011-07-27 02:41:57
【问题描述】:

这是我的整个存储过程:

CREATE OR REPLACE PROCEDURE "CTI"."TEMP_DIVISION"
(
    pDivisionList in varchar2,
    out_cursor out SYS_REFCURSOR
)
as
begin
  open out_cursor for
  SELECT distinct CTA_DIVISION
  FROM cti_account 
  WHERE CTA_DIVISION in (pDivisionList);  
END;

如果我传入 TPA,它会将 TPA 作为 1 行返回(正确)。如果我传入 CFL,它将 CFL 作为 1 行返回(正确)。但是,我想做的是传入 TPA,CFL 并让它像 WHERE CTA_DIVISION in ('TPA','CFL') 一样运行,返回 2 行数据,但这并没有发生。它不返回任何行。我需要更改什么才能传递该字符串并返回 2 行? TIA

【问题讨论】:

标签: oracle stored-procedures where-in


【解决方案1】:

我认为您可以调整 Oracle: passing a list as bind variable 以适合您的情况。

要使 varchar2 作为列表或单个值工作,您需要将 pDivisionList 解析为一个数组(可能是一个值)并将其传递给另一个过程(可以在您的过程中定义)。 )

WRT 到 @frustratedwithformsdesigner 的解决方案,动态 sql 容易受到 sql-injection 的影响。请注意此类解决方案。

【讨论】:

  • 看来关键是WHERE empno in (SELECT * FROM TABLE( CAST ( ? as NUMBER_LIST_TYPE ) ) )...非常聪明(虽然我从未尝试过)!!这个技巧需要最低版本吗?
  • 那行得通。此外,这有助于asktom.oracle.com/pls/apex/…
  • @frustratedwithformsdesigner 正确。我应该强调这一点。我不确定,但 CAST 可能已在 11g 中引入。 TYPE 已经存在了很长时间。
【解决方案2】:

这可能通过动态 SQL 来完成。像这样构建查询:

sql_str := 'SELECT distinct CTA_DIVISION
  FROM cti_account 
  WHERE CTA_DIVISION in ('||pDivisionList||')'; 

然后在上面使用execute immediate。当然,您必须确保pDivisionList 的格式为"'a','b','c'"

当然,动态 SQL 存在潜在的 SQL 注入问题,因此请确保您可以完全控制进入 pDivisionList 的内容。

【讨论】:

    【解决方案3】:

    更简单的方法是:

    SELECT distinct CTA_DIVISION
    FROM cti_account 
    WHERE INSTR(','||pDivisionList||',', ','||CTA_DIVISION||',') > 0;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-03
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      • 2015-06-11
      • 2014-09-23
      • 1970-01-01
      相关资源
      最近更新 更多