Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle Cast using %TYPE attribute

I want to cast a value using %TYPE attribute in my SQL statement. The %TYPE attribute lets you use the datatype of a field, record, nested table, database column, or variable in your own declarations, rather than hardcoding the type names.

This works:

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

But I would like to

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:

Can this (or something similar) be done?

EDIT: What I'm trying to achieve is: when t2.v is to large I want to truncate it. I'm trying to avoid using substr with a hard coded field length. So cast(v as t1.v%TYPE) instead of substr(v,1,1)

like image 769
Rob van Laarhoven Avatar asked Oct 18 '12 09:10

Rob van Laarhoven


People also ask

What does %type do in Oracle?

The %TYPE attribute lets you declare a constant, variable, collection element, record field, or subprogram parameter to be of the same data type as a previously declared variable or column (without knowing what that type is).

How do you use %type in PL SQL?

You can use the %TYPE attribute as a datatype specifier when declaring constants, variables, fields, and parameters. If the types that you reference change, your declarations are automatically updated. This technique saves you from making code changes when, for example, the length of a VARCHAR2 column is increased.

Can we use CAST function in Oracle?

The CAST function can be used in the following versions of Oracle/PLSQL: Oracle 12c, Oracle 11g, Oracle 10g, Oracle 9i.

What does %type do when it is used?

The %TYPE attribute, used in PL/SQL variable and parameter declarations, is supported by the data server. Use of this attribute ensures that type compatibility between table columns and PL/SQL variables is maintained.


1 Answers

%TYPE is only available in PL/SQL, and can only be used in the declaration section of a block. So, you can't do what you're attempting.

You might think you could declare your own PL/SQL (sub)type and use that in the statement:

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

... but that also won't work, because cast() is an SQL function not a PL/SQL one, and only recognises built-in and schema-level collection types; and you can't create an SQL type using the %TYPE either.


As a nasty hack, you could do something like:

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

Which would be slightly more palatable if you could have that length stored in a variable - a substitution or bind variable in SQL*Plus, or a local variable in PL/SQL. For example, if it's a straight SQL update through SQL*Plus you could use a bind variable:

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;

Something similar could be done in other set-ups, it depends where the insert is being performed.

like image 130
Alex Poole Avatar answered Sep 19 '22 16:09

Alex Poole