如何在动态 sql 查询中添加 where 条件?

How to add where condition in a dynamic sql query?

我正在尝试编写一个使用动态查询获取不同记录的过程tables.Now我想向该子句添加 where 条件。该过程采用一个输入参数,我想使用此参数来比较 table 中存在的相同参数的值。以下代码不起作用,我不确定如何让它起作用。

SQL> create or replace procedure p_count(x IN varchar2) as
  2    type   arr is varray(5) of varchar2(30);
  3    tables arr := arr('tb1', 'tb2', 'tb3');
  4    cnt    number;
  5  begin
  6     for i in 1 .. tables.count loop
  7       execute immediate 'select count(*) from ' || tables(i) ||' where tables(i).column_name ='||x into cnt;
  8       insert into tb6 values(tables(i), cnt);
  9     end loop;
 10  end;
 11  /

根据您发布的评论,应该是这样的:

示例 table(tb1 只有一列:category;您的可能有更多列;不想创建其他 table,所以我在循环中使用了异常处理部分,它不会引发错误并让您循环直到结束)。

SQL> SET SERVEROUTPUT ON
SQL>
SQL> SELECT * FROM tb1;

CATEGORY
--------
A
B
B

SQL>

程序:

SQL> CREATE OR REPLACE PROCEDURE p_count (x IN VARCHAR2)
  2  AS
  3     TYPE arr IS VARRAY (5) OF VARCHAR2 (30);
  4
  5     tables  arr := arr ('tb1', 'tb2', 'tb3');
  6     cnt     NUMBER;
  7     l_str   VARCHAR2 (500);
  8  BEGIN
  9     FOR i IN 1 .. tables.COUNT
 10     LOOP
 11        BEGIN
 12           l_str :=
 13                 'select count(*) from '
 14              || tables (i)
 15              || ' where category ='
 16              || DBMS_ASSERT.enquote_literal (x);
 17
 18           EXECUTE IMMEDIATE l_str
 19              INTO cnt;
 20
 21           INSERT INTO tb6
 22                VALUES (tables (i), cnt);
 23        EXCEPTION
 24           WHEN OTHERS
 25           THEN
 26              DBMS_OUTPUT.put_line (tables (i) || ': ' || SQLERRM);
 27        END;
 28     END LOOP;
 29  END;
 30  /

Procedure created.

测试:

SQL> EXEC p_count('A');
tb2: ORA-00942: table or view does not exist
tb3: ORA-00942: table or view does not exist

PL/SQL procedure successfully completed.

SQL>

结果:

SQL> SELECT * FROM tb6;

NAME        CNT
---- ----------
tb1           1

SQL>

您可以使用:

create or replace procedure p_count(x IN varchar2)
as
  type   arr is varray(5) of varchar2(30);
  tables arr := arr('tb1', 'tb2', 'tb3');
  cnt    number;
begin
  for i in 1 .. tables.count loop
    execute immediate 'select count(*)
                       from   ' || DBMS_ASSERT.SIMPLE_SQL_NAME(tables(i)) || '
                       where  column_name = :1'
                 INTO  cnt
                 USING x;
    insert into tb6 values(tables(i), cnt);
  end loop;
end;
/

其中,对于示例数据:

CREATE TABLE tb1 (column_name) AS
SELECT 'aaa' FROM DUAL;

CREATE TABLE tb2 (column_name) AS
SELECT 'bbb' FROM DUAL;

CREATE TABLE tb3 (column_name) AS
SELECT 'aaa' FROM DUAL UNION ALL
SELECT 'aaa' FROM DUAL UNION ALL
SELECT 'bbb' FROM DUAL;

CREATE TABLE tb6 (
  table_name VARCHAR2(30),
  cnt        NUMBER(10,0)
);

之后:

BEGIN
  p_count('aaa');
END;
/

tb6 包含:

TABLE_NAME CNT
tb1 1
tb2 0
tb3 2

db<>fiddle here