使用变量作为子查询执行查询
Posted
技术标签:
【中文标题】使用变量作为子查询执行查询【英文标题】:Perform a query with a variable as subquery 【发布时间】:2019-05-22 09:01:44 【问题描述】:我有一个这样的查询:
select * from SOURCE
where A = 'a'
and B in (
select SOMECOLUMN from VERY_LONG_QUERY
WHERE SOMECHECK = 'some check'
)
我想将上面的查询转换成这样的语句 PL/SQL:
veryLongQueryVar := 'select SOMECOLUMN from VERY_LONG_QUERY WHERE SOMECHECK = ''some check'' '
select * from SOURCE
where A = 'a'
and B in veryLongQueryVar
这怎么可能?
【问题讨论】:
您希望这样做会怎样? 为什么需要这样做?如果需要动态生成部分查询,您正在查看动态 sql。一般来说,静态 sql 更好(更易于维护,更不容易发生 sql 注入等) 这听起来像动态 SQL,您可以使用execute immediate
。这听起来也不是一个好主意。您可能正在尝试解决错误的问题。
我的想法是拆分 2 个查询,以便其他开发人员更清晰易读。另外,我做了一个只有一个子查询的示例,但在我的实际案例中,我有 3 个嵌套查询。
【参考方案1】:
您可以使用WITH
clause 实现类似的效果:
with veryLongQueryVar as
(select SOMECOLUMN from VERY_LONG_QUERY WHERE SOMECHECK = 'some check')
select * from SOURCE
where A = 'a'
and B in (select SOMECOLUMN from veryLongQueryVar)
您还可以使用SELECT INTO
将很长的查询结果选择为变量(某种类型的表)和use table
to pass it into IN。但这会导致两个单独的查询,您似乎想避免这种情况。
【讨论】:
【参考方案2】:这里有一个建议,你可以做什么。
您将长查询中的值存储在一个集合中,并在另一个选择中使用它。
declare
TYPE my_collection IS TABLE OF SOMECOLUMN%type
INDEX BY number;
tab my_collection ;
rec SOURCE%rowtype;
begin
select SOMECOLUMN
bulk collect into tab
from VERY_LONG_QUERY
WHERE SOMECHECK = 'some check';
select * into rec
from SOURCE
where A = 'a'
and B in (select column_value from table(tab);
end;
您还可以创建动态 SQL 字符串。
declare
TYPE cur IS REF CURSOR;
my_cur cur;
veryLongQueryVar varchar2(32000);
begin
veryLongQueryVar := 'select SOMECOLUMN from VERY_LONG_QUERY WHERE SOMECHECK = ''some check'' '
veryLongQueryVar := 'select * from SOURCE
where A = ''a''
and B in ('||veryLongQueryVar ||')'
open my_cur for veryLongQueryVar ;
....
end;
【讨论】:
我收到了这个错误:PLS-00103: Encountered the symbol "OPEN" when expecting one of the following: * & = - + ; < / > at in is mod remainder not rem <an exponent (**)> <> or != or ~= >= <= <> and or like like2 like4 likec between || multiset member submultiset 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error.
以上是关于使用变量作为子查询执行查询的主要内容,如果未能解决你的问题,请参考以下文章