Oracle PL/SQL 标量变量大小语法歧义
Oracle PL/SQL Scalar Variable Size Syntax Ambiguity
在 PL/SQL 包中允许使用哪些类型的表达式来声明标量变量的大小?
这里是 db<>fiddle 显示大小表达式而不是数字文字,其中一些会产生错误,而另一些则不会。下面是一个片段。
create or replace package p as
vc varchar2(length('four'));
end;
/
Package created.
但是
create or replace package p as
vc varchar2(greatest(3,4)); --PLS-00491: numeric literal required
end;
/
ORA-24344: success with compilation error
前面带有 length()
的示例表明允许使用数字文字以外的表达式。
length()
和 greatest()
都是 SQL 函数。为什么一个函数调用 PLS-00491
而另一个不调用?
注意:文档Scalar Variable Declaration.
中似乎没有提供指定PL/SQL datatype
大小的语法
使用 Oracle 19c 企业版。
提前致谢。
我怀疑这是因为 length()
函数是确定性的 - 字符串文字 'four' 的字符长度始终为 4 - 而 greatest()
则不是。如图in the documentation,受NLS设置影响;所以在使用我的默认 English/binary 设置时,我看到了这个:
select greatest('á', 'b') from dual;
GREATEST('Á','B')
-----------------
á
如果我更改设置,我会得到不同的结果:
alter session set nls_comp = 'linguistic';
alter session set nls_language = 'spanish';
select greatest('á', 'b') from dual;
GREATEST('Á','B')
-----------------
b
虽然您现在比较数字不受 NLS 设置的影响,但它是相同的功能,所以它仍然不是确定性的。
因此,至少在理论上,基于 greatest()
声明的 PL/SQL 变量的大小可能会因会话设置而异,这是不可行的。
在 PL/SQL 包中允许使用哪些类型的表达式来声明标量变量的大小?
这里是 db<>fiddle 显示大小表达式而不是数字文字,其中一些会产生错误,而另一些则不会。下面是一个片段。
create or replace package p as
vc varchar2(length('four'));
end;
/
Package created.
但是
create or replace package p as
vc varchar2(greatest(3,4)); --PLS-00491: numeric literal required
end;
/
ORA-24344: success with compilation error
前面带有 length()
的示例表明允许使用数字文字以外的表达式。
length()
和 greatest()
都是 SQL 函数。为什么一个函数调用 PLS-00491
而另一个不调用?
注意:文档Scalar Variable Declaration.
中似乎没有提供指定PL/SQLdatatype
大小的语法
使用 Oracle 19c 企业版。
提前致谢。
我怀疑这是因为 length()
函数是确定性的 - 字符串文字 'four' 的字符长度始终为 4 - 而 greatest()
则不是。如图in the documentation,受NLS设置影响;所以在使用我的默认 English/binary 设置时,我看到了这个:
select greatest('á', 'b') from dual;
GREATEST('Á','B')
-----------------
á
如果我更改设置,我会得到不同的结果:
alter session set nls_comp = 'linguistic';
alter session set nls_language = 'spanish';
select greatest('á', 'b') from dual;
GREATEST('Á','B')
-----------------
b
虽然您现在比较数字不受 NLS 设置的影响,但它是相同的功能,所以它仍然不是确定性的。
因此,至少在理论上,基于 greatest()
声明的 PL/SQL 变量的大小可能会因会话设置而异,这是不可行的。