9

我想在我的 SQL 语句中使用 %TYPE 属性转换一个值。%TYPE 属性允许您在自己的声明中使用字段、记录、嵌套表、数据库列或变量的数据类型,而不是硬编码类型名称。

这有效:

insert into t1  select cast(v as varchar2(1)) from t2;

但我想

insert into t1  select cast(v as t1.v%TYPE) from t2;

Error starting at line 16 in command:
insert into t1  select cast(v as t1.v%TYPE) from t2
Error at Command Line:16 Column:37
Error report:
SQL Error: ORA-00911: Ongeldig teken.
00911. 00000 -  "invalid character"
*Cause:    identifiers may not start with any ASCII character other than
           letters and numbers.  $#_ are also allowed after the first
           character.  Identifiers enclosed by doublequotes may contain
           any character other than a doublequote.  Alternative quotes
           (q'#...#') cannot use spaces, tabs, or carriage returns as
           delimiters.  For all other contexts, consult the SQL Language
           Reference Manual.
*Action:

可以这样做(或类似的事情)吗?

编辑:我想要实现的是:当 t2.v 太大时,我想截断它。我试图避免使用带有硬编码字段长度的 substr 。所以 cast(v as t1.v%TYPE) 而不是 substr(v,1,1)

4

1 回答 1

7

%TYPE仅在 PL/SQL 中可用,并且只能在block 的声明部分中使用。所以,你不能做你正在尝试的事情。

您可能认为您可以声明自己的 PL/SQL(子)类型并在语句中使用它:

declare
    subtype my_type is t1.v%type;
begin
    insert into t1 select cast(v as my_type) from t2;
end;
/

...但这也行不通,因为cast()SQL 函数不是 PL/SQL 函数,并且只识别内置和模式级别的集合类型;并且您不能使用任何一个创建SQL 类型%TYPE


作为一个讨厌的黑客,你可以这样做:

insert into t1 select substr(v, 1,
    select data_length
    from user_tab_columns
    where table_name = 'T1'
    and column_name = 'V') from t2;

如果您可以将该长度存储在一个变量中——SQL*Plus 中的替换或绑定变量,或者 PL/SQL 中的局部变量,那么这会稍微好一些。例如,如果它是通过 SQL*Plus 的直接 SQL 更新,您可以使用绑定变量:

var t1_v_len number;
begin
    select data_length into :t1_v_len
    from user_tab_columns
    where table_name = 'T1' and column_name = 'V';
end;
/
insert into t1 select substr(v, 1, :t1_v_len) from t2;

在其他设置中可以进行类似的操作,这取决于执行插入的位置。

于 2012-10-18T10:12:13.683 回答