2012-10-18 4 views
6

Ich möchte einen Wert mit% TYPE-Attribut in meiner SQL-Anweisung zu werfen. Mit dem% TYPE-Attribut können Sie den Datentyp eines Felds, Datensatzes, einer geschachtelten Tabelle, einer Datenbankspalte oder einer Variablen in Ihren eigenen Deklarationen verwenden, anstatt die Typnamen fest zu codieren.Oracle Cast mit% TYPE-Attribut

Dies funktioniert:

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

Aber würde ich

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: 

Kann diese (oder so ähnlich) getan werden, um

gefallen hat?

EDIT: Was ich versuche zu erreichen ist: Wenn t2.v zu groß ist, möchte ich es abschneiden. Ich versuche zu vermeiden, substr mit einer fest codierten Feldlänge zu verwenden. Daher wird (0 als t1.v% TYPE) anstelle von substr (v, 1,1)

Antwort

5

%TYPE nur in PL/SQL verfügbar und kann nur in declaration section of a block verwendet werden. Also, du kannst nicht tun, was du versuchst.

Sie vielleicht denken Sie Ihre eigene PL/SQL (sub) eingeben und verwenden, die in der Erklärung erklären könnten:

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

... aber das auch, weil cast() eine Funktion SQL ist keine PL/SQL-Version und erkennt nur integrierte und Schema-Level-Collection-Typen; und Sie können auch keine SQL type mit der %TYPE erstellen.


Als gemeiner Hack, könnten Sie so etwas wie:

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

die etwas schmackhafter sein würde, wenn man diese Länge in einer Variablen gespeichert haben könnte - eine Substitution oder Bind-Variable in SQL * Plus oder eine lokale Variable in PL/SQL. Zum Beispiel, wenn es ein gerade SQL-Update über SQL * plus Sie könnten einen Bind-Variable verwenden:

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; 

Etwas ähnliches könnte in anderen Set-ups durchgeführt werden, es hängt, wo der Einsatz durchgeführt wird.

+1

'+ 1', Herzlichen Glückwunsch zu erreichen' 10k' :) –

+0

@PeterLang - danke * 8-) Rate mal, ich gehe besser und lese dann über die Moderator Tools ... –

+0

@Alex Das ist genau das, was ich bin versuchen zu erreichen. Wenn t2.v zu groß ist, möchte ich es abschneiden. Ich versuche zu vermeiden, substr mit einer fest codierten Feldlänge zu verwenden. So Cast (v wie t1.v% TYPE) anstelle von substr (v, 1,1) –