这本书在过程重载方面自相矛盾吗

does this book contradict itself on procedure overloading

DECLARE
TYPE DateTyp IS TABLE OF DATE INDEX BY PLS_INTEGER;
TYPE NumTyp IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
hiredate DateTyp;
sal NumTyp;
PROCEDURE initial(tab OUT DateTyp, n INTEGER) IS
BEGIN
FOR i IN 1..n LOOP
tab(i) := SYSDATE;
END LOOP;
END initial;
PROCEDURE initial(tab OUT NumTyp, n INTEGER) IS
BEGIN
FOR i IN 1..n LOOP
tab(i) := 0.0;
END LOOP;
END initial;
BEGIN
Initial(hiredate, 50);  --calls first(DateTyp) version
initial(sal, 100);  --calls second(NumTyp) version
END;

他们给出了这个例子(他们说这是有效的)来说明子程序重载..."They differ only in their parameter types."

但随后他们给出了这个限制指南:

You cannot overload two subprograms that differ only in their subtypes. For example, you cannot overload the following two subprograms:

DECLARE
...
PROCEDURE withdraw(amount INTEGER) IS
BEGIN ... END;
PROCEDURE withdraw(amount REAL) IS
BEGIN ... END;

我没有看到或理解什么....他们通过仅更改参数类型来给出示例,他们说这是有效的(第一个示例)....然后他们说这是不允许的

第一个示例仅将制表符从 DateTyp 更改为 NumTyp....然后第二个示例仅将金额从 INTEGER 更改为 REAL...

PL/SQL 文档有一个有用的附录,我认为它有助于解释差异。 Find it here.

它将支持的数据类型分成系列。 DATE、NUMBER 和 VARCHAR2 是不同的系列。具有不同数据类型系列(例如 DATE 和 VARCHAR2)参数的重载过程是不同的,因此是允许的。具有来自相同数据类型系列(REAL 和 INTEGER)的参数的重载过程没有区别,因为它们都是 NUMBER 类型。因此,它们是不允许的。

基本上,这个调用引用了第二个过程的哪个实例?

withdraw(200);

谁也说不准。

这两个例子并不矛盾。 DateType 是 TABLE OF DATE; NumTyp 是一个 TABLE OF NUMBER。这些是截然不同的类型。 INTEGER 和 REAL 都是 NUMBER 的子类型,在 STANDARD 包中定义为:

type NUMBER is NUMBER_BASE;
 subtype FLOAT is NUMBER; -- NUMBER(126)
 subtype REAL is FLOAT; -- FLOAT(63)
 subtype "DOUBLE PRECISION" is FLOAT;
 subtype INTEGER is NUMBER(38,0);

所以 INTEGER 是 NUMBER 的直接子类型,而 REAL 是 FLOAT 的子类型,而 FLOAT 是 NUMBER 的子类型。因此,INTEGER 和 REAL 都是 NUMBER 的子类型,因此不能作为重载子程序之间的唯一区别。