Benutzer-Werkzeuge

Webseiten-Werkzeuge


prog:orcle_datatype_long

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
prog:orcle_datatype_long [2014/08/06 13:22] gpipperrprog:orcle_datatype_long [2016/10/24 12:53] (aktuell) – [Java JDBC und LONG Datentypen] gpipperr
Zeile 1: Zeile 1:
 +===== Der Datentyp LONG und LONG RAW in der Oracle Datenbank =====
 +
 +Als grundlegende Regel gilt, dass die "historischen" Binary Datentypen nicht mehr verwendet werden sollten.
 +
 +Mit RAW und LONG gibt es diverse Einschränkungen, vom Lesen der Daten bis zur hin zu Replikation.
 +
 +Statt Long oder RAW sollte die "modernen" Datentypen BLOB/CLOB etc. verwendet werden.
 +
 +
 +Allerdings sind im Data Dictionary der Datenbank selber auch in 11g R2 immer noch LONG Datentypen im Einsatz.
 +
 +
 +
 +==== Direkte Ausgabe der Wert in SQL*Plus ====
 +
 +In SQL Plus können die Werte einfach ausgelesen werden, dazu zuvor aber mit "set long 32767" den SQL*Plus Buffer konfigurieren.
 +
 +Zum Beispiel um den den "Less Value" Wert auf einer Partition aus zu lesen:
 +<code sql>
 +
 +-----------------------------
 +-- Long values Vorbereitung
 +-----------------------------
 +
 +set long 32767
 +
 +
 +select    p.partition_position
 +       ,  p.partition_name
 +       ,  p.HIGH_VALUE
 +       ,  s.bytes
 +  from dba_tab_partitions p
 +     , dba_segments s  
 +where p.table_owner like upper('&OWNER.')
 +  and p.table_name like upper('&TAB_NAME.')
 +  and p.table_name= s.SEGMENT_NAME (+)
 +  and p.partition_name= s.PARTITION_NAME (+)
 +  and p.table_owner = s.owner (+)
 +order by p.partition_position  
 +/
 +
 +
 +</code>
 +
 +==== Formatieren einer Long Spalte mit UTL_RAW ====
 +
 +Leider steht keine interne Default Funktion wie to_char zur Verfügung einen Long Value direkt in char/varchar2 in SQL zu konvertieren.
 +
 +Im [[ http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_raw.htm#BABJHEGF#i997085|UTL_RAW (siehe hier die Oracle Original Doku) ]]  Package stehen aber für die Verarbeitung von Long Values in PL/SQL zwei Funktionen zur Verfügung,  CAST_TO_VARCHAR2 und  CAST_TO_RAW.
 +
 +==== Einfachste Version einer Hilfsfunktion zum Auslesen von EBDIC bzw einer DEC Daten in long Row Spalten in einer SAP Tabelle ===
 +
 +DEC = DEC MCS character  = Digital Equipment Corporation Multinational Character Set
 +
 +
 +<code sql>
 +
 +
 +-- Wie werden die Zeichen in Hex dargestellt:
 +-- auf den Zeichensatz der SQL*Plus Session achten!
 +
 +
 +sql>select dump(convert('Kostenübernahme','AL32UTF8','WE8ISO8859P15')) from dual;
 +
 +DUMP(CONVERT('KOSTENüBERNAHME','AL32UTF8','WE8ISO8859P15'))
 +----------------------------------------------------------------------------------
 +Typ=1 Len=18: 75,111,115,116,101,110,195,130,194,129,98,101,114,110,97,104,109,101
 +
 +
 +--EBDIC Zeichensatz 'WE8EBCDIC500'
 +
 +sql>select dump(convert('Kostenübernahme','AL32UTF8','WE8EBCDIC500')) from dual;
 +
 +DUMP(CONVERT('KOSTENüBERNAHME','WE8ISO8859P15','WE8EBCDIC500'))
 +-----------------------------------------------------------------------------------------------------
 +Typ=1 Len=24: 46,63,195,139,195,136,195,129,62,66,97,195,130,195,129,195,138,62,47,195,135,95,195,129
 +
 +
 +-- das Ganze nun als RAW Wert
 +
 +sql>select utl_raw.cast_to_raw(CONVERT('Kostenübernahme','WE8ISO8859P15','WE8EBCDIC500')) from dual;
 +
 +UTL_RAW.CAST_TO_RAW(CONVERT('KOSTENüBERNAHME','WE8ISO8859P15','WE8EBCDIC500'))
 +-------------------------------------------------------------------------------------------------------------------
 +2E3FCBC8C13E4261C2C1CA3E2FC75FC1
 +
 +
 +-- Hier am Beispiel einer Test Tabelle:
 +--
 +
 +create table rawtest (id number, wert long raw);
 +
 +
 +--
 +-- 1 Test mit hex Angabe des Strings
 +insert into rawtest 
 +values ( 1
 +        , hextoraw('2E3FCBC8C13E4261C2C1CA3E2FC75FC1'))
 +/
 +
 +-- 2 Test mit EBDIC Text und Convert
 +insert into rawtest 
 +values (  2 
 +        , utl_raw.cast_to_raw(convert('Kostenübernahme','WE8ISO8859P15','WE8EBCDIC500'))
 +)
 +/
 +
 +
 +-- Funktion anlagen 
 +-- Tabelle mit dem PK auslesen und den Wert in eine Variable schreiben
 +-- Wert dann je nach Bedarf konvertieren
 +--
 +
 +create or replace function readRawtoVarchar2(p_id number)
 +return varchar2
 +as
 + v_raw long raw;
 + v_return varchar2(32000);
 +begin
 + select wert into v_raw 
 +   from rawtest where id=p_id;
 +
 + v_return:=utl_raw.cast_to_varchar2(v_raw);
 +
 +        -- je nach dem wie der Zeichensatz der Umgebung steht entsprechend umwandeln
 +
 + return convert(v_return,'WE8EBCDIC500','WE8ISO8859P15');
 +end;
 +/
 +
 +--------------------------------------------------------------------------------------
 +-- Konkrete Umsetzung für die Tabelle T003T
 +
 +CREATE OR REPLACE FUNCTION readRawtoVarchar2T003T(p_key varchar2)
 +RETURN varchar2
 +AS
 +   v_raw long raw;
 +   v_return varchar2(32000);
 +BEGIN
 +   SELECT vardata INTO v_raw 
 +     FROM atab 
 +    WHERE tabname = 'T003T'
 +      and varkey = p_key;
 +        
 +  v_return:=substr(utl_raw.cast_to_varchar2(utl_raw.substr(v_raw,5)),1,99);
 +       
 +  -- je nachdem wie der Zeichensatz der Umgebung steht entsprechend umwandeln
 +   RETURN CONVERT(v_return,'WE8DEC','WE8ISO8859P15');
 +   
 +END;
 +/
 +
 +--
 +--
 +--Auslesen
 +
 +select readRawtoVarchar2(id) as wert from rawtest where id=1;
 +
 +
 +WERT
 +-----------------
 +Kostenübernahme
 +--
 +
 +select readRawtoVarchar2(id) from rawtest where id=2;
 +
 +
 +WERT
 +-----------------
 +Kostenübernahme
 +--
 +
 +</code>
 +
 +
 +=== Test mit LONG RAW ===
 +
 +Hier ein Versuch mit Hilfe eines Ref Cursor das ganze flexible zu gestalten. 
 +Leider kann ein generischer Ref Cursor mit einer Long Spalte aber in SQL*Plus nicht erzeugt werden .-( .
 +
 +<code sql>
 +
 +-- Test Table
 +create table t (id number, value long raw);
 +
 +insert into t values (1,utl_raw.cast_to_raw('This is a message .-) '));
 +commit;
 +
 +-- Erster Versuch:
 +
 +SQL>select utl_raw.cast_to_varchar2(value) from t;
 +
 +select utl_raw.cast_to_varchar2(value) from t
 +                                *
 +ERROR at line 1:
 +ORA-00997: illegal use of LONG datatype
 +
 +
 +-- Hilfsfunktion definieren
 +
 +create or replace function read(p_cursor sys_refcursor) return varchar2 is
 +  v_long   long raw;
 +  v_return varchar2(32000);
 +  v_id     number;
 +begin
 +  loop
 +    fetch p_cursor
 +      into v_id;
 +    exit when p_cursor%notfound;
 +    select value into v_long from t where id = v_id;
 +    v_return := utl_raw.cast_to_varchar2(v_long);
 +    --v_return:='-';
 +  end loop;
 +  return v_return;
 +end;
 +
 +
 +
 +-- Abfragen mit dem Erzeugen eines Cursor Objects in SQL*Plus
 +
 +select read(cursor(select id from t)) from dual;
 +
 +</code>
 +
 +
 +=== Test mit LONG ===
 +
 +Der reine LONG Datentyp ist etwas einfacher zu handhaben, in PL/SQL ist ein implizierter Cast nach Varchar2 möglich.
 +
 +
 +<code sql>
 +
 +--test Tabelle
 +create table t (id number, value long);
 +
 +insert into t values (1,('This is a message .-) '));
 +commit;
 +
 +
 +
 +-- Test Hilfsfunktion für PL/SQL 
 +
 +create or replace function read(p_cursor sys_refcursor) return varchar2 is
 +  v_return varchar2(32000);
 +  v_id     number;
 +begin
 +  loop
 +    fetch p_cursor
 +      into v_id;
 +    exit when p_cursor%notfound;
 +  
 +    -- Bei Long ist kein explizter Cast notwendig!
 +  
 +    select value into v_return from t where id = v_id;
 +  
 +  end loop;
 +  return v_return;
 +end;
 +/
 +
 +
 +-- Abfragen mit dem Erzeugen eines Cursor Objects in SQL*Plus
 +
 +select read(cursor(select id from t)) from dual;
 +
 +</code>
 +
 +=== Tabelle mit einem  Long Datentyp umkopieren ===
 +
 +Mit PL/SQL kann dann auch die Migration einer Tabelle mit Long Spalten in eine CLOB Spalte erfolgen.
 +
 +<code sql>
 +
 +--test Tabelle
 +create table t2 (id number, value clob);
 +
 +set serveroutput on
 +
 +declare
 +  v_cursor sys_refcursor;
 +  v_value  long;
 +  v_id     number;
 +  v_count  pls_integer := 0;
 +begin
 +  open v_cursor for
 +    select id
 +          ,value
 +      from t;
 +  loop
 +    fetch v_cursor
 +      into v_id
 +          ,v_value;
 +  
 +    exit when v_cursor%notfound;
 +  
 +    insert into t2
 +      (id
 +      ,value)
 +    values
 +      (v_id
 +      ,v_value);
 +    v_count := v_count + 1;
 +  
 +    -- commit every 1000 rows
 +    if mod(v_count, 1000) = 0 then
 +      commit;
 +    end if;
 +  
 +  end loop;
 +  close v_cursor;
 +  commit;
 +  dbms_output.put_line(rpad('-', 35, '-'));
 +  dbms_output.put_line('Info :: Insert Row Count :: ' || to_char(v_count));
 +  dbms_output.put_line(rpad('-', 35, '-'));
 +end;
 +/
 +
 +
 +</code>
 +
 +
 +
 +
 +
 +==== Java JDBC und LONG Datentypen ====
 +
 +Links:
 +
 +  * http://docs.oracle.com/cd/F49540_01/DOC/java.815/a64685/basic4.htm
 +
 +
 +----
 +
 +==== Nach BLOB konvertieren ====
 +
 +
 +Function **to_lob** verwenden:
 +  * https://docs.oracle.com/database/121/SQLRF/functions221.htm#SQLRF06134
 +
 +
 +----
 +
 +==== Quellen ====
 +
 + * http://docs.oracle.com/cd/B19306_01/server.102/b14200/expressions005.htm
 + * http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_raw.htm#i1003994
  
prog/orcle_datatype_long.txt · Zuletzt geändert: 2016/10/24 12:53 von gpipperr