如何在动态 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
我正在尝试编写一个使用动态查询获取不同记录的过程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