[Oracle] Spalte inkl Definition kopieren

Yaslaw

alter Rempler
Moderator
Ich versuche eine Spalte zu kopieren. Nicht die Daten, nein die Spaltendefinitoin

Das folgende mit %TYPE geht leider nicht, zeigt aber in welche Richtung ich gehen will.
SQL:
ALTER TABLE tbl_b
ADD(
    feld_b tbl_a.feld_a%TYPE
);

Achja, es sollte SQL sein, nicht PL/SQL (greiffe leider über sas darauf zu und das ist alles andere als Lustig).
Von mir aus kann man auch mit einem SELECT den korrekten Type auslesen.
Das Problem mit all_tab_columns ist, dass man den Typenstring je nach Type unterschiedlich zusammenschustern müsste. bei VARCHAR2 und CHAR muss die Länge angegeben werden, bei DATE darf sie nicht dabei sein etc.

Mir fehlt also das SQL-Auslesen des Types in der Form
Code:
VARHCAR2(50)
CHAR(20)
DATE
NUMBER
 
Zuletzt bearbeitet von einem Moderator:
evtl. ist das hier ein Anfang:
SQL:
SELECT
  column_name,
  nullable,
  concat(concat(concat(data_type,'('),data_length),')') as 'Type'
FROM all_tab_columns
WHERE 
   table_name='TABLE_NAME_TO_DESCRIBE';

Und wenn die Klammern bei Date stören evtl. da für diesen Fall ein CASE WHEN...
 
Zuletzt bearbeitet von einem Moderator:
Das Problem mit all_tab_columns ist, dass man den Typenstring je nach Type unterschiedlich zusammenschustern müsste. bei VARCHAR2 und CHAR muss die Länge angegeben werden, bei DATE darf sie nicht dabei sein etc.

Mir fehlt also das SQL-Auslesen des Types in der Form
Code:
VARHCAR2(50)
CHAR(20)
DATE
NUMBER
Das hatte ich auch schon ausprobiert. Doch bei einem Datumsfeld gibt das DATE(7) zurück was beim ALTER TABLE auf einen Fehler läuft.
Ich weiss, ich könnte den DATA_TAPE mittels CASE unterscheiden. Doch finde ich das nicht gerade sexy wenn ich jeden Datentype definieren muss.
 
nicht trivial, denke ich. Mit Code könnte man die DBMS_METADATA-API anzapfen: http://docs.oracle.com/cd/E11882_01/server.112/e22490/metadata_api.htm#i1013157 und daraus etwas basteln. Wahrscheinlich könnte man in ähnlicher Weise auch ein ALTER TABLE per Script via SQL generieren (was sicher umständlicher wäre mit instr, substr etc.), aber eine einfache Variante mir einer Art rowtype kenne ich nicht.

Ergänzend noch ein kleines DBMS_METADATA-Beispiel, weil das einfach ein nettes Werkzeug ist:

Code:
SQL> create table test (a number, b date);

Tabelle wurde erstellt.

SQL> select dbms_metadata.get_ddl('TABLE', 'TEST') from dual;

DBMS_METADATA.GET_DDL('TABLE','TEST')
------------------------------------------------------------------

  CREATE TABLE "TEST"."TEST"
   (    "A" NUMBER,
        "B" DATE
   ) SEGMENT CREATION DEFERRED
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  TABLESPACE "USERS"

Gruß

Martin
 
Zuletzt bearbeitet:
Der Ansatz ist nciht schlecht. Ich versuchte mitels REGEXP_SUBSTR() die entsprechende Stelle auszulesen. Noch habe ich das passende Pattrn leider nicht zusammen..

Nachtrag: So scheints zu gehen
SQL:
-- Die folgenden Parameter kommen dann von aussen. Darum sind sie auch in UPPER() gesetzt
-- mytable, feld_alt, feld_neu
SELECT
  CONCAT(
    'ALTER TABLE mytable ADD ',
    REPLACE(
        REGEXP_SUBSTR(
          dbms_metadata.get_ddl('TABLE', UPPER('mytable')),
          '^\s*"feld_alt" [A-Z0-9]+(\([^\)]+\)|)[^,\)]*',
          1,1,
          'im'    
      ),
      UPPER('feld_alt'),
      UPPER('feld_neu')
    )
  )AS ddl
FROM dual;

Ausgabe
SQL:
ALTER TABLE mytable ADD 	"FELD_NEU" VARCHAR2(1 CHAR) NOT NULL ENABLE
 
Zuletzt bearbeitet von einem Moderator:
Zurück