我的记录类型如下,
TYPE x_Rec IS RECORD(
master_company x_tab.master_company%TYPE,
report_trans_type x_tab.report_trans_type%TYPE,
balance_version_id x_tab.balance_version_id%TYPE,
reporting_entity x_tab.reporting_entity%TYPE,
year_period_from x_tab.year_period%TYPE,
year_period_to x_tab.year_period%TYPE,
journal_id x_tab.journal_id%TYPE,
row_id x_tab.row_id%TYPE);
我使用此记录创建了一个表类型:
TYPE x_rec_tab IS TABLE OF x_Rec INDEX BY PLS_INTEGER;
我想在过程中将此表类型用作默认的null参数。
PROCEDURE x_Balance___(x_param IN NUMBER,
x_rec_ IN x_rec_tab default null)
IS
BEGIN
...My code
END;
它提供以下错误消息
PLS-00382:表达式类型错误
答案 0 :(得分:1)
您不能使用an associative array执行此操作,因为never be null可以使用don't have constructors。如果您尝试将null分配给类型为x_rec_tab
的变量,则会出现相同的错误。它们也varray,因此您不能使用空集合。
您可以nested table或更有效地针对您的情况执行此操作"No 'Access-Control-Allow-Origin' header is present on the requested resource":
create or replace package p42 as
TYPE x_Rec IS RECORD(
master_company x_tab.master_company%TYPE,
report_trans_type x_tab.report_trans_type%TYPE,
balance_version_id x_tab.balance_version_id%TYPE,
reporting_entity x_tab.reporting_entity%TYPE,
year_period_from x_tab.year_period%TYPE,
year_period_to x_tab.year_period%TYPE,
journal_id x_tab.journal_id%TYPE,
row_id x_tab.row_id%TYPE);
-- no index-by clause, so nested table not associative array
TYPE x_rec_tab IS TABLE OF x_Rec;
end p42;
/
Package P42 compiled
show errors
No errors.
create or replace package body p42 as
PROCEDURE x_Balance___(x_param IN NUMBER,
x_rec_ IN x_rec_tab default null)
IS
BEGIN
--...My code
null;
END;
PROCEDURE dummy IS
l_rec_tab x_rec_tab;
BEGIN
l_rec_tab := null;
END;
end p42;
/
Package Body P42 compiled
show errors;
No errors.
您也可以默认使用空集合:
PROCEDURE x_Balance___(x_param IN NUMBER,
x_rec_ IN x_rec_tab default x_rec_tab())
IS
...
如果您有其他代码依赖于类型为关联数组,那么这对您没有多大帮助。
答案 1 :(得分:0)
旧问题但仍有帮助。 您可以创建一个函数:
function empty_tab
return x_rec_tab
as
l_tab x_rec_tab;
begin
return l_tab;
end empty_tab;
这样你可以(注意 empty_tab 用作默认参数):
PROCEDURE x_Balance___(x_param IN NUMBER,
x_rec_ IN x_rec_tab default empty_tab)
IS
BEGIN
...My code
END;
答案 2 :(得分:0)
我通过在过程签名中使用CAST(null为 your_type /)来解决此问题。
例如,在您的情况下,它将是这样的:
程序x_Balance(x_param IN NUMBER, x_rec_ IN x_rec_tab默认强制转换(null为x_rec_tab))
然后,在该过程中,您只需要使用count方法检查x_rec_是否包含元素。
这种方式适合我。
答案 3 :(得分:0)
这是@ManuelPerez回答的重复,但我只是觉得可以更好地解释它。
创建此过程,将可选变量转换为数据类型,如下所示:
CREATE OR REPLACE PROCEDURE Test_Procedure (
txt_ IN VARCHAR2,
col_formats_ IN dbms_sql.varchar2a DEFAULT cast(null as dbms_sql.varchar2a) )
IS BEGIN
Dbms_Output.Put_Line (txt_);
FOR i_ IN 1 .. 10 LOOP
IF col_formats_.EXISTS(i_) THEN
Dbms_Output.Put_Line (i_ || ' Exists');
ELSE
Dbms_Output.Put_Line (i_ || ' DOES NOT Exist');
END IF;
END LOOP;
END Test_Procedure;
之所以超过公认的答案,是因为它不需要您更改传入变量的数据类型。根据您的情况,您可能没有灵活性。
如果您有一个变量来填充过程,则现在这样调用过程:
DECLARE
txt_ VARCHAR2(100) := 'dummy';
arr_ dbms_sql.varchar2a;
BEGIN
arr_(4) := 'another dummy';
Test_Procedure (txt_, arr_);
END;
或者如果不这样做,就这样:
DECLARE
txt_ VARCHAR2(100) := 'dummy';
BEGIN
Test_Procedure (txt_);
END;
您的输出将如下所示:
dummy
1 DOES NOT Exist
2 DOES NOT Exist
3 DOES NOT Exist
4 Exists
5 DOES NOT Exist
6 DOES NOT Exist
7 DOES NOT Exist
8 DOES NOT Exist
9 DOES NOT Exist
10 DOES NOT Exist