【问题标题】: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 个嵌套查询。

标签: sql oracle plsql


【解决方案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.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多