使用变量作为子查询执行查询

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.

以上是关于使用变量作为子查询执行查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL之子查询

Python-Sqlalchemy-Postgres:如何将子查询结果存储在变量中并将其用于主查询

6-SQL子查询

第五章 复杂查询 5-2 子查询

SQL嵌套子查询和相关子查询的执行过程有啥区别

SQL嵌套子查询和相关子查询的执行过程有啥区别