【问题标题】:variable as column name in where clause in Oracle PL/SQL变量作为 Oracle PL/SQL 中 where 子句中的列名
【发布时间】:2015-01-21 15:13:39
【问题描述】:

我正在处理 PL/SQL 代码,我需要在 where 子句中使用变量作为列名来执行选择查询。列名作为 varchar 存储在表中,我使用循环将这些列名传递给我的 select 语句。

请找到我正在尝试运行的示例代码段:

set serveroutput on;

declare
var varchar2(100);
counter number;
begin

var:='description';
select count(*) 
into counter
            from nodetable
           where  var like '%Ship%';

dbms_output.put_line(counter);
end;

输出:

anonymous block completed
0

但是结果应该是 86。 Oracle 将最后一个条件作为两个字符串而不是 column=string 进行比较。

请让我知道这在 oracle 中是否可行,或者是否有解决方法。

问候 Ankit

【问题讨论】:

  • “列名作为 varchar 存储在表中” 这很令人困惑。你是说你有一个表,它的行包含其他表的列名?就像标准的USER_TAB_COLUMNS。还是别的什么?
  • 是的,列名作为行存储在另一个表中,就像标准 user_tab_columns 一样。
  • 您示例中的 WHERE 子句与提到的表中的信息无关,这就是您得到错误结果的原因。每个 WHERE/AND 子句在某些时候都应该引用 FROM 子句中列出的对象中的列名。好吧,在基本的 SQL 中这是正确的。存在更复杂的陈述,但您的情况确实如此。
  • 所以你有一个描述列的表。你也有一个描述表格的吗?
  • 不,列数据类型未存储在该表中,只是存在列名。另外,根据我的要求,我只希望列名出现在 where 子句中。其中“列名”类似于“某事”

标签: sql database oracle plsql


【解决方案1】:

您必须使用动态 SQL,最好使用绑定变量:

EXECUTE IMMEDIATE 
   'select count(*) from nodetable where '||var||' like :p1' 
   INTO counter 
   USING '%Ship%'; 

【讨论】:

    【解决方案2】:

    试试这个

    declare
    var varchar2(100);
    counter number;
    begin
    
    var:='description';
    EXECUTE IMMEDIATE
    'select count(*) 
    into counter
                from nodetable
               where  '||var||' like ''%Ship%'' ';
    
    dbms_output.put_line(counter);
    end;
    

    您需要小心冒号的 (')。

    【讨论】:

      【解决方案3】:

      我同意之前在实施中的回答,但我强烈建议您更改您的技术要求,因为您不能为此使用绑定变量,并且它是潜在的注入位置。例如,如果有人将存储列名的表中的值编辑为类似这样的内容:“description = injection_function or description”。然后你的动态 sql 块会执行这条语句:

      select count(*) from nodetable where description = inject_function or description like '%Ship%
      

      函数的示例实现

      create function inject_function
      return varchar2
      is pragma autonomous_transaction;
      begin
          delete * from most_important_table;
          commit;
          return to_char(null);
      exception when others then
          rollback;
          return to_char(null);
      end;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-16
        • 1970-01-01
        • 2016-05-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多