Sql 根据某些条件查询表A或表B

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

在Oracle DB(12)中,我有两个表:

表:步骤详情

+-----------+---------+---------------+
| 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
    变量的值是多余的, 因为只要没有,查询将毫无例外地返回零 找到匹配的记录
  • 关键字
    函数
    应以
    创建[或替换]
  • 以其名称结束存储函数是可选的(可能是 (被忽略)

表名不能用作动态SQL中的绑定变量。如果某个联合查询引发“未找到数据”异常,会发生什么情况?假设我们要从第一个表开始计数,因此第一个查询工作正常,但由于某种原因,第二个查询失败,因为找不到数据。这将如何影响整个功能?无论是哪个表,如果两个查询中的一个失败,您将得到零计数结果,而不是未找到数据;如果一个表没有给出结果,则得到另一个表的记录数。如果两个查询都给出零,则结果为零