Sql 根据某些条件查询表A或表B
在Oracle DB(12)中,我有两个表: 表:步骤详情Sql 根据某些条件查询表A或表B,sql,oracle,plsql,stored-functions,Sql,Oracle,Plsql,Stored Functions,在Oracle DB(12)中,我有两个表: 表:步骤详情 +-----------+---------+---------------+ | record_id | step_id | material_type | +===========+=========+===============+ | 1 | 1 | in | +-----------+---------+---------------+ | 2 | 1
+-----------+---------+---------------+
| record_id | step_id | material_type |
+===========+=========+===============+
| 1 | 1 | in |
+-----------+---------+---------------+
| 2 | 1 | in |
+-----------+---------+---------------+
| 3 | 1 | out |
+-----------+---------+---------------+
| 4 | 2 | in |
+-----------+---------+---------------+
| 5 | 2 | out |
+-----------+---------+---------------+
| 6 | 2 | out |
+-----------+---------+---------------+
表:行动详情
+-----------+-----------+---------------+
| record_id | action_id | material_type |
+===========+===========+===============+
| 1 | 11 | in |
+-----------+-----------+---------------+
| 2 | 11 | out |
+-----------+-----------+---------------+
| 3 | 12 | in |
+-----------+-----------+---------------+
| 4 | 12 | out |
+-----------+-----------+---------------+
所有id列的类型均为整数
我需要计算两个表的输入材料。
在PL/SQL块中,我有以下函数,每个函数都有“几乎”相同的查询:
--count from step_details:
FUNCTION get_step_input_count(p_step_id step_details.step_id%TYPE)
RETURN INTEGER
IS
l_count INTEGER := 0;
BEGIN
SELECT COUNT(1)
INTO l_count
FROM step_details
WHERE step_id = p_step_id
AND material_type = 'in';
RETURN l_count;
END get_step_input_count;
--count from action_details:
FUNCTION get_action_input_count(p_action_id action_details.action_id%TYPE)
RETURN INTEGER
IS
l_count INTEGER := 0;
BEGIN
SELECT COUNT(1)
INTO l_count
FROM action_details
WHERE action_id = p_action_id
AND material_type = 'in';
RETURN l_count;
END get_action_input_count;
是否可以编写一条SELECT语句,根据某些条件每次可以查询两个表中的一个,因此我将最终编写一个函数,使用一个查询而不是两个函数,类似于:
FUNCTION get_input_count(p_parent_id integer,
p_from varchar2)
RETURN INTEGER
IS
l_count INTEGER := 0;
BEGIN
SELECT COUNT(1)
INTO l_count
FROM (when p_from = 'S' then 'step_details'
when p_from = 'A' then 'action_details')
WHERE (when p_from = 'S' then 'step_id = p_parent_id'
when p_from = 'A' then 'action_id = p_parent_id')
AND material_type = 'in';
RETURN l_count;
END get_input_count;
您可以尝试以下方法:
select sum(num_rows)
from
(
select count(*) as num_rows
from tab1 /* first table */
where :param = 1
union all
select count(*) as num_rows
from tab2 /* second table */
where :param = 2
)
在这里,您使用一个
select
,它包装来自所有可能表的查询的UNION ALL
;每个表都会根据某些参数的值给出其贡献值,因此您只能根据参数值从表中获取所需的行。您也可以使用如下动态SQL。
在这种情况下,应该注意SQL注入
sql_statement := 'select count(*)';
IF table = 'xxx'
THEN
sql_statement := sql_statement || ' from xxx where material_type = ''in''';
ELSIF table = 'yyy'
sql_statement := sql_statement || ' from yyy where yyyy_type = ''in''';
END IF;
sql_statement := sql_statement blur blur;
EXECUTE IMMEDIATE sql_statement INTO l_count USING p_1;
一个选项是使用动态SQL,该SQL由表名和列名的连接组成,并为值使用一个绑定变量,该值将是从每个表查询的公共值(
p\u parent\u id
)
SQL> CREATE OR REPLACE FUNCTION get_input_count(p_parent_id INT, p_from VARCHAR2) RETURN INT IS
l_count INT;
crs SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_from VARCHAR2(32);
v_col VARCHAR2(99);
BEGIN
SELECT DECODE(p_from,'A','actions_details','S','step_details'),
DECODE(p_from,'A','action_id','S','step_id')
INTO v_from, v_col
FROM dual;
v_sql := 'SELECT COUNT(*)
FROM '||v_from||'
WHERE material_type = ''in'' AND '||v_col||' = :prt_id';
OPEN crs FOR v_sql USING p_parent_id;
LOOP
FETCH crs INTO l_count;
EXIT WHEN crs%NOTFOUND;
END LOOP;
CLOSE crs;
RETURN l_count;
END;
/
在哪里
- 用零初始化
变量的值是多余的, 因为只要没有,查询将毫无例外地返回零 找到匹配的记录l_count
- 关键字
应以函数
创建[或替换]
- 以其名称结束存储函数是可选的(可能是 (被忽略)