我在下面创建了一个基本示例,该示例显示了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 :(得分:3)
将大小报告为4000似乎并不是一个问题 - 您实际上无法将长值放入(假设您的函数只返回短值),并且它是&#39 ;不喜欢它浪费空间。
但如果您希望它更整洁并且显示为更小的尺寸,则可以使用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