我有一个过程,它接收一个记录作为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。
答案 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;