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

倖福魔咒の 提交于 2019-12-01 05:21:05

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:

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

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.

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:

WHERE myColumn in (SELECT temp_value FROM temp_table)

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)":

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
                    $1 as criteria_list,
                    instr($1, ',', 1, level) as comma_pos
                from
                    dual
                connect by
                    instr($1, ',', 1, level) > 0 and instr($1, ',', 1, level) <= instr($1, ',', -1)
                union all
                select
                    $1,
                    0
                from
                    dual
            )
        )
    )
)
select * from some_table where column in (select item from criteria)

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

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

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

,foo@bar.com,ammoq@ammoq.com,onemore@whatever.com,
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!