2015-02-06 44 views
0

我在下面创建了一个基本示例,其中显示了Oracle中具有虚拟列的表。虚拟列由函数填充。Oracle中由函数填充的虚拟列的数据类型长度

create or replace 
function awesomeness(
    val in varchar2 
) 
    return varchar2 deterministic as retVal varchar2(255); 
    begin 
    retVal := 'Some amazing value'; 
    return retval; 
    end; 
/ 

drop table sometable; 
/
create table sometable( 
    value varchar2(255), 
    awesome varchar2(4000) as (awesomeness(value)) 
); 
/

上面的SQL执行得很好,但实际上我并不满意4000个字符的'真棒'列。我想让这个更小,但根据documentation on functions - 你不能。但它表明它适应呼叫者,除非它似乎没有这样做。

该数据类型不能指定长度,精度或比例。 Oracle数据库从调用函数的环境中派生返回值的长度,精度或比例。

如果我将表格定义更改为如下所示,我得到一个错误。

drop table sometable; 
/
create table sometable( 
    value varchar2(255), 
    awesome varchar2(30) as (awesomeness(value)) 
); 
/

Error report: 
SQL Error: ORA-12899: value too large for column "AWESOME" (actual: 30, maximum: 4000) 
12899. 00000 - "value too large for column %s (actual: %s, maximum: %s)" 
*Cause: An attempt was made to insert or update a column with a value 
      which is too wide for the width of the destination column. 
      The name of the column is given, along with the actual width 
      of the value, and the maximum allowed width of the column. 
      Note that widths are reported in characters if character length 
      semantics are in effect for the column, otherwise widths are 
      reported in bytes. 
*Action: Examine the SQL statement for correctness. Check source 
      and destination column data types. 
      Either make the destination column wider, or use a subset 
      of the source column (i.e. use substring). 

我的虚拟列真的需要varchar2(4000)还是我可以以某种方式减少它?

+0

我想我可以串为30个字符,但为什么我应该需要做的,当它的已经定义。 – mrswadge 2015-02-06 15:02:33

+0

我不认为你可以创建一个用户定义类型为“VARCHAR2(30)”?即通过CREATE TYPE? – Ditto 2015-02-06 15:10:17

回答

3

有报道为4000的尺寸并没有真正似乎是一个问题 - 你不会真正能够把长值反正(假设你的函数只返回短的),并且它不喜欢它的浪费空间。

但是,如果你希望它是整洁和显示为更小的尺寸,你可以使用cast(),这是不一样对待其他功能(甚至是内置的像substr()):

create table sometable( 
    value varchar2(255), 
    awesome varchar2(30) as (cast(awesomeness(value) as varchar2(30))) 
); 

Table sometable created. 

desc sometable 

Name Null Type   
------- ---- ------------- 
VALUE  VARCHAR2(255) 
AWESOME  VARCHAR2(30) 

如果你的函数以某种方式返回一个更长的值 - 因为它可能在你的例子中,因为retVal是255,尽管你的字符串文字足够短 - 你的虚拟列值将被截断为30个字符。

与原有的功能,这是当虚拟列是它所返回太小会发生什么:

create table sometable( 
    value varchar2(255), 
    awesome varchar2(10) as (cast(awesomeness(value) as varchar2(10))) 
); 

insert into sometable (value) values ('X'); 

select awesome from sometable; 

AWESOME 
---------- 
Some amazi