为什么视图列的类型与相应的函数结果类型不匹配?
Why type of a view column does not match corresponding function result type?
假设有一个函数 my_pkg.get_prop_of
,即 return 类型 CHAR(5)
的值。
另外让我们声明一个视图 my_view
,其中有一列 prop
,从这个函数调用中获取它的值。
create or replace package my_pkg AS
subtype short_string is CHAR(5);
function get_prop_of(pi_name char)
return short_string;
end;
create or replace package body my_pkg AS
function get_prop_of(pi_name char)
return short_string is
begin
return substr(pi_name || 'abcde', 1, 5);
end;
end;
---
create or replace view my_view as
select
my_pkg.get_prop_of('x') as prop
from dual;
您能否解释一下为什么数据字典将该列类型显示为 VARCHAR2(4000)
,这种行为的目的是什么?
select table_name, data_Type, data_length
from all_tab_cols
where table_name = 'MY_VIEW';
----------------------------------------------------
TABLE_NAME | COLUMN_NAME | DATA_TYPE | DATA_LENGTH
----------------------------------------------------
MY_VIEW | PROP | VARCHAR2 | 4000
看起来数据字典包含让编译器在视图编译时应用它所需的数据。但不知为什么它不会那样做。
select object_name, package_name, data_type, data_length, in_out
from all_arguments
where object_name = 'GET_PROP_OF';
-----------------------------------------------------------------
OBJECT_NAME | PACKAGE_NAME | DATA_TYPE | DATA_LENGTH | IN_OUT
-----------------------------------------------------------------
GET_PROP_OF | MY_PKG | CHAR | 5 | OUT <- return type
GET_PROP_OF | MY_PKG | CHAR | | IN
我想以一种清晰的方式获得列类型和函数结果类型的匹配。
据了解,像CAST(val AS CHAR(5))
这样的硬铸造可以暂时解决问题,
但是有没有更优雅的方法,它还可以处理更改函数 return 类型的情况,而无需更改列中各处的 CAST
表达式,调用该函数。
因为在创建 VIEW
时,Oracle 不知道从 function
返回的 function
结果的最大值,但它知道数据类型。
此外,事实是 --> function
的任何返回值都不能包含 data precision
.
您仍然可以通过使用 CAST
控制 VIEW
查询中的数据类型和精度来实现您想要的效果,如下所示:
SQL>
SQL> CREATE OR REPLACE VIEW MY_VIEW AS
2 SELECT
3 CAST(MY_PKG.GET_PROP_OF('x') AS VARCHAR2(5)) AS PROP
4 FROM
5 DUAL;
View created.
SQL> DESC MY_VIEW;
Name Null? Type
----------------------------------------- -------- ----------------------------
PROP VARCHAR2(5)
SQL>
干杯!!
因为您使用函数创建视图
create or replace view my_view as
select
substr(my_pkg.get_prop_of('x'),0,5) q
from dual;
select table_name, data_Type, data_length
from dba_tab_cols
where table_name = 'MY_VIEW';
MY_VIEW VARCHAR2 5
假设有一个函数 my_pkg.get_prop_of
,即 return 类型 CHAR(5)
的值。
另外让我们声明一个视图 my_view
,其中有一列 prop
,从这个函数调用中获取它的值。
create or replace package my_pkg AS
subtype short_string is CHAR(5);
function get_prop_of(pi_name char)
return short_string;
end;
create or replace package body my_pkg AS
function get_prop_of(pi_name char)
return short_string is
begin
return substr(pi_name || 'abcde', 1, 5);
end;
end;
---
create or replace view my_view as
select
my_pkg.get_prop_of('x') as prop
from dual;
您能否解释一下为什么数据字典将该列类型显示为 VARCHAR2(4000)
,这种行为的目的是什么?
select table_name, data_Type, data_length
from all_tab_cols
where table_name = 'MY_VIEW';
----------------------------------------------------
TABLE_NAME | COLUMN_NAME | DATA_TYPE | DATA_LENGTH
----------------------------------------------------
MY_VIEW | PROP | VARCHAR2 | 4000
看起来数据字典包含让编译器在视图编译时应用它所需的数据。但不知为什么它不会那样做。
select object_name, package_name, data_type, data_length, in_out
from all_arguments
where object_name = 'GET_PROP_OF';
-----------------------------------------------------------------
OBJECT_NAME | PACKAGE_NAME | DATA_TYPE | DATA_LENGTH | IN_OUT
-----------------------------------------------------------------
GET_PROP_OF | MY_PKG | CHAR | 5 | OUT <- return type
GET_PROP_OF | MY_PKG | CHAR | | IN
我想以一种清晰的方式获得列类型和函数结果类型的匹配。
据了解,像CAST(val AS CHAR(5))
这样的硬铸造可以暂时解决问题,
但是有没有更优雅的方法,它还可以处理更改函数 return 类型的情况,而无需更改列中各处的 CAST
表达式,调用该函数。
因为在创建 VIEW
时,Oracle 不知道从 function
返回的 function
结果的最大值,但它知道数据类型。
此外,事实是 --> function
的任何返回值都不能包含 data precision
.
您仍然可以通过使用 CAST
控制 VIEW
查询中的数据类型和精度来实现您想要的效果,如下所示:
SQL>
SQL> CREATE OR REPLACE VIEW MY_VIEW AS
2 SELECT
3 CAST(MY_PKG.GET_PROP_OF('x') AS VARCHAR2(5)) AS PROP
4 FROM
5 DUAL;
View created.
SQL> DESC MY_VIEW;
Name Null? Type
----------------------------------------- -------- ----------------------------
PROP VARCHAR2(5)
SQL>
干杯!!
因为您使用函数创建视图
create or replace view my_view as
select
substr(my_pkg.get_prop_of('x'),0,5) q
from dual;
select table_name, data_Type, data_length
from dba_tab_cols
where table_name = 'MY_VIEW';
MY_VIEW VARCHAR2 5