oracle 如何在oracle sql的WHERE IN子句中传递变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4462415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 22:13:06  来源:igfitidea点击:

how to pass a variable in WHERE IN clause of oracle sql?

sqloraclestringwhere-clause

提问by Ravi Gupta

Hi
I have a variable $1 which hold comma separated email addresses like [email protected],[email protected] . I wish to pass this variable in a where clause like

嗨,
我有一个变量 $1 ,它保存逗号分隔的电子邮件地址,如 [email protected],[email protected] 。我希望在一个 where 子句中传递这个变量,比如

where myColumn in ()

But obviously this won't work, I tried APEX_UTIL.STRING_TO_TABLE and DBMS_UTILITY.COMMA_TO_TABLE but in vain.

但显然这行不通,我尝试了 APEX_UTIL.STRING_TO_TABLE 和 DBMS_UTILITY.COMMA_TO_TABLE 但徒劳无功。

Any help appreciated.

任何帮助表示赞赏。

采纳答案by Dan

As Pavanred alluded to, the easiest way -- though not necessarily the best -- is to interpolate the values yourself. You don't say what your calling language is, but something like:

正如 Pavanred 所暗示的,最简单的方法——虽然不一定是最好的——是自己插入这些值。你没有说你的呼叫语言是什么,而是说:

sql = "SELECT something FROM whatever WHERE myColumn in (" +  + ")"

However, this means it's very important that you have pre-checked all the values in $1 to make sure that they are either numbers, or properly escaped strings, or whatever else it is that you need to pass but cannot be raw values supplied by a user, to avoid a SQL injection.

但是,这意味着您必须预先检查 $1 中的所有值以确保它们是数字或正确转义的字符串,或者您需要传递但不能是由用户,以避免 SQL 注入。

The other option is to make it a two-step process. First, insert the values from $1 into a temporary table, then select those values as a subquery:

另一种选择是使其成为一个两步过程。首先,将 $1 中的值插入到临时表中,然后选择这些值作为子查询:

WHERE myColumn in (SELECT temp_value FROM temp_table)

回答by Jeremy Shimanek

It's not pretty, but you can achieve a 100% one-step SQL injection-proof solution like this. You plug in the "criteria" CTE to your query, which parses the comma-sperated list into a table. Then you can use it in an in query like "where column in (select item from criteria)":

这并不漂亮,但您可以像这样实现 100% 的一步式 SQL 防注入解决方案。您将“标准”CTE 插入到您的查询中,这会将逗号分隔的列表解析为一个表。然后你可以在查询中使用它,比如“where column in(从条件中选择项目)”:

with criteria as
(
    select
        substr(criteria_list, item_start, item_length) as item
    from
    (
        select
            criteria_list,
            comma_pos + 1 as item_start,
            nvl(next_comma_pos - 1, length(criteria_list)) - comma_pos as item_length
        from
        (
            select
                criteria_list,
                comma_pos,
                lead(comma_pos) over(order by comma_pos) as next_comma_pos
            from
            (
                select
                     as criteria_list,
                    instr(, ',', 1, level) as comma_pos
                from
                    dual
                connect by
                    instr(, ',', 1, level) > 0 and instr(, ',', 1, level) <= instr(, ',', -1)
                union all
                select
                    ,
                    0
                from
                    dual
            )
        )
    )
)
select * from some_table where column in (select item from criteria)

回答by Erich Kitzmueller

A simple workaround, which might be good enough in your case (but is not performant), is to use LIKE instead:

一个简单的解决方法,在您的情况下可能足够好(但性能不佳),是使用 LIKE 代替:

select * from something where  like '%,'||mycolumn||',%';

$1 is your comma separated list, as a string, with a comma prepended and appended, e.g.

$1 是你的逗号分隔列表,作为一个字符串,在前面和附加一个逗号,例如

,[email protected],[email protected],[email protected],