如何检查记录是否为空

时间:2017-02-06 11:31:31

标签: oracle plsql record

我有一个过程,它接收一个记录作为IN参数(该过程也有一个OUT参数。)

CREATE OR REPLACE PACKAGE p
  PROCEDURE p_select( p_filter_params IN t_filter_params
                    , p_order_list OUT SYS_REFCURSOR);
END p;

CREATE OR REPLACE PACKAGE BODY p
  PROCEDURE p_select( p_filter_params IN t_filter_params
                    , p_order_list OUT SYS_REFCURSOR) AS
  BEGIN
    IF p_filter_params IS NULL
      THEN
        NULL;
    END IF;
  END p_select,
END p;

可执行部分

DECLARE
  TYPE t_filter_params IS RECORD
    ( f_name    customers.cust_first_name%TYPE
    , l_name    customers.cust_last_name%TYPE
    , city      customers.cust_address.city%TYPE
    , from_date orders.order_date%TYPE
    , to_date   orders.order_date%TYPE);

  vr_params t_filter_params;

  TYPE ref_cursor IS REF CURSOR;

  v_cursor ref_cursor;

BEGIN
  /*vr_params.f_name := 'john';
  vr_params.l_name := 'smith';
  vr_params.city := 'Dallas';
  vr_params.from_date := SYSDATE - 100;
  vr_params.to_date := SYSDATE;*/

  --p.p_select(vr_params, v_cursor);
  p.p_select(null, v_cursor);
end;

有人可以告诉我如何使程序中的IF语句正常工作吗?

非常感谢, Mikcutu。

4 个答案:

答案 0 :(得分:1)

一种解决方案是使用反向逻辑。例如不可能问:

IF my_record IS NULL THEN
   do something;
END IF;

IF my_record.my_attibute IS NULL THEN
   do something;
END IF;

相反,可以问:

IF my_record.my_attibute IS NOT NULL THEN
   go on processing;
ELSE
   do something;
END IF;

答案 1 :(得分:0)

记录有点特别。如果将记录设置为null,则所有记录属性都设置为null,但记录本身仍然存在。

我想到的第一件事就是检查记录中是否有某种id为空 - 这意味着该记录为空。

你没有id,但是这可能导致另一个解决方案:添加另一个属性,只要它没有被填充,它就是null。

第三种方法:只需检查每个属性并检查每个属性is null

最后,最好,拒绝使用RECORD并使用OBJECT代替:它完全按照您的预期运作。

答案 2 :(得分:0)

我相信你不能:

SQL> create or replace package p is
  2      type tType is record ( a number, b number);
  3      --
  4      procedure proc(pIn IN tType);
  5  end;
  6  /

Package created.

SQL> create or replace package body p is
  2      procedure proc(pIn IN tType) is
  3      begin
  4          if pIn is null then
  5              dbms_output.put_line('NULL');
  6          else
  7              dbms_output.put_line('NOT NULL');
  8          end if;
  9      end;
 10  end;
 11  /

Warning: Package Body created with compilation errors.

SQL> sho err
Errors for PACKAGE BODY P:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/9      PL/SQL: Statement ignored
4/12     PLS-00306: wrong number or types of arguments in call to 'IS
         NULL'

使用稍微不同的方法,您可以使用模式级别类型:

SQL> create or replace type tType is object ( a number, b number);
  2  /

Type created.

SQL> create or replace package p2 is
  2      --
  3      procedure proc(pIn IN tType);
  4  end;
  5  /

Package created.

SQL> create or replace package body p2 is
  2      procedure proc(pIn IN tType) is
  3      begin
  4          if pIn  is null then
  5              dbms_output.put_line('NULL');
  6          else
  7              dbms_output.put_line('NOT NULL');
  8          end if;
  9      end;
 10  end;
 11  /

Package body created.

SQL>

答案 3 :(得分:0)

不要通过记录复杂化,只需传递个别参数:

CREATE OR REPLACE PACKAGE p
AS
  PROCEDURE p_select(
    in_f_name    customers.cust_first_name%TYPE
  , in_l_name    customers.cust_last_name%TYPE
  , in_city      customers.cust_address.city%TYPE
  , in_from_date orders.order_date%TYPE
  , in_to_date   orders.order_date%TYPE
  , out_order_list OUT SYS_REFCURSOR
  );
END p;

CREATE OR REPLACE PACKAGE BODY p
AS
  PROCEDURE p_select(
    in_f_name    customers.cust_first_name%TYPE
  , in_l_name    customers.cust_last_name%TYPE
  , in_city      customers.cust_address.city%TYPE
  , in_from_date orders.order_date%TYPE
  , in_to_date   orders.order_date%TYPE
  , out_order_list OUT SYS_REFCURSOR
  ) AS
  BEGIN
    OPEN out_order_list FOR
    SELECT *
    FROM   orders o INNER JOIN customers c ON ( o.customer_id = c.customer_id )
    WHERE  ( in_f_name IS NULL OR c.cust_first_name = in_f_name )
    OR     ( in_l_name IS NULL OR c.cust_last_name  = in_l_name )
    OR     ( in_city   IS NULL OR c.cust_address.city = in_city )
    OR     ( in_from_date IS NULL OR o.order_date >= in_from_date )
    OR     ( in_to_date   IS NULL OR o.order_date <= in_to_date );
  END p_select,
END p;