سؤال

Procedures in PL/SQL can have default values for parameters, but the caller can pass values that are identical to the default values. Is there a way from within the PL/SQL to determine whether a parameter is passed? As implied this cannot be done by comparing the value with the default value.

هل كانت مفيدة؟

المحلول

It might be possible if you consider overloading a procedure. Suppose you want the default of 5 for parameter a and 7 for parameter b and want also to check if the parameters were passed. In this case you have to overload the procedure 4 times for each combination of (with and without parameter). Finally, the real thing happens in the private procedure p_:

set serveroutput on size 100000 format wrapped

create or replace package tq84_test_pck as

   procedure p;
   procedure p(a number          );
   procedure p(          b number);
   procedure p(a number, b number);

end tq84_test_pck;
/

create or replace package body tq84_test_pck as

    procedure p_(a number := 5, a_default boolean,
                 b number := 7, b_default boolean) as
    begin

        dbms_output.put_line(
             'a: ' || a || 
             case when a_default then ' [default]'
                                 else ' [passed ]' end);

        dbms_output.put_line(
             'b: ' || b || 
             case when b_default then ' [default]'
                                 else ' [passed ]' end);

        dbms_output.new_line;

    end p_;

    procedure p is
    begin
        p_(a_default => true, 
           b_default => true);
    end p;

    procedure p (a number) is
    begin
        p_(a         => a, 
           a_default => false, 
           b_default => true);
    end p;

    procedure p (b number) is
    begin
        p_(b         => b, 
           a_default => true, 
           b_default => false);
    end p;

    procedure p (a number, b number) is
    begin
        p_(a         => a,
           b         => b, 
           a_default => false, 
           b_default => false);
    end p;

end tq84_test_pck;
/

show errors

declare

begin

   tq84_test_pck.p;
   tq84_test_pck.p( b => 7);
   tq84_test_pck.p( a => 7 );
   tq84_test_pck.p( a => null);
   tq84_test_pck.p( a => 5, b => 6);

end;
/

نصائح أخرى

So the way I do this is I don't use default values. Or rather, I set them to NULL as default. Then within my procedure body I check to see if it's equal to NULL and if so set it to a sane default. At that point you could mangle a flag or two in the same space to see what's being set or not set.

However, there's the edge case of if they intended to pass in NULL for some reason. However, most devs don't deal well with tripletcase, so I don't usually worry about that (additionally, if I'm passing in a value, I need to pass a value, not null, so null for me means never-was-defined)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى dba.stackexchange
scroll top