SQL Spalten in Zeilen

ajaekel

Newbie
Registriert
Feb. 2010
Beiträge
3
Hallo zusammen,

ich zerbreche mir schon die ganze Zeit den Kopf, wie ich folgendes unter ORA lösen kann:

Ich muss für eine Datenübernahme eine eindeutige Umschlüsselungstabelle der Altdaten aufbereiten. Dabei sind in einigen Spalten jedoch kommaseparierte Wertelisten enthalten und nicht pro Wert eine eigene Zeile in der Tabelle. Die Daten sehen dabei so aus:

Zeile 1 der Tabelle: 'A', 'B', 'C, D'
Zeile 2 der Tabelle: 'A', 'E', 'F'


Ich möchte daraus jetzt folgendes erhalten:
Zeile 1: 'A', 'B', 'C'
Zeile 2: 'A', 'B', 'D'
Zeile 3: 'A', 'E', 'F'

Das Problem dabei ist, dass die Anzahl der Werte in der Werteliste schwankt - ich also irgendwie so lange aus einer Spalte Zeilen erzeugen muss, wie Werte in der Spalte vorhanden sind.

Kann mir einer von Euch dabei helfen?

Danke & Gruß,
Achim
 
Hallo,

genau das ist ja mein Problem :)

Wie müsste das im Ansatz aussehen? Bin leider kein Entwickler.

Gruß,
Achim
 
Ohne ein Minimum an Programmierkenntnissen wirst du da wahrscheinlich nicht viel machen können.
 
Also mit reinem SQL wirst du an die Grenzen stoßen, leichter wird es wenn du dafür PLSQL verwendest. Mit anderen Worten ich würde da eine Stored Function aufrufen die für mich das Parsen erledigt. Jetzt meine Frage: In wieweit hast du Erfahrungen mit PLSQL, Stored Procedures/Functions in Oracle? Desweiteren welche Version von Oracle verwendest du? Welche Tools hast du (SqlDeveloper, SQLPlus, Worksheet)? Alternativ reicht auch nur ein PLSQL Block, muss nicht zwingend eine Stored Function sein...
 
Zuletzt bearbeitet:
Hallo,

Entwickler bin ich nicht - habe aber schon ab und an ein wenig in SQL gemacht. Zur Lösung habe ich bisher folgendes selber schon versucht:

DECLARE
nRecno int;
vcSAP_AUFTRART VARCHAR (20);
vcSAP_VBA VARCHAR (20);
vcSAP_POSART VARCHAR (20);
vcSAP_PREISGR VARCHAR (20);
vcSAP_PREISSCHL VARCHAR (20);
vcSAP_LIEFERART VARCHAR (20);
vcSAP_BEZPER VARCHAR (20);
vcEVT_AUFLAGID VARCHAR2 (60);
vcEVT_AUFLAGIDNEU VARCHAR2 (20);
vcEVT_LIEFERID VARCHAR2 (20);
vcEVT_LPOSTID VARCHAR2 (20);
vcEVT_RABSATZ VARCHAR2 (20);
vcEVT_ZALART VARCHAR2 (20);
vcEVT_LANDID VARCHAR2 (20);
vcEVT_OBJID VARCHAR2 (20);

nGesamt NUMBER (5);
nStartPos NUMBER (5);
nEndPos NUMBER (5);
nPosSep NUMBER (5);

CURSOR CUR1
IS
SELECT RECNO,
SAP_AUFTRART,
SAP_VBA,
SAP_POSART,
SAP_PREISGR,
SAP_PREISSCHL,
SAP_LIEFERART,
SAP_BEZPER,
EVT_AUFLAGID,
EVT_LIEFERID,
EVT_LPOSTID,
EVT_RABSATZ,
EVT_ZALART,
EVT_LANDID,
EVT_OBJID
FROM vs_msd_umschl
WHERE recno = 82; --Ein Datensatz mit mehreren Werten in der Spalte EVT_AUFLAGID
BEGIN
OPEN CUR1;

nStartPos := 1; --Startposition im String
nPosSep := nvl(INSTR (vcEVT_AUFLAGID, ',', nStartPos),0); --Position des ersten Kommas im String

FETCH CUR1
INTO
nRECNO,vcSAP_AUFTRART, vcSAP_VBA, vcSAP_POSART, vcSAP_PREISGR, vcSAP_PREISSCHL, vcSAP_LIEFERART, vcSAP_BEZPER, vcEVT_AUFLAGID, vcEVT_LIEFERID, vcEVT_LPOSTID, vcEVT_RABSATZ, vcEVT_ZALART, vcEVT_LANDID, vcEVT_OBJID;
IF nPosSep = 0 THEN
vcEVT_AUFLAGIDNEU := vcEVT_AUFLAGID;--Wenn kein Komma im String gefunden wird, müssen keine separaten Zeilen erzeugt werden
ELSE BEGIN
WHILE (nPosSep > 0) LOOP -- so lange Komma gefunden werden, muss die Schleife durchlaufen werden, um daraus separate Zeilen zu erzeugen
nPosSep := INSTR (vcEVT_AUFLAGID, ',', nStartPos);--nächstes Komma im String ab StartPos
--nGesamt := LENGTH (vcEVT_AUFLAGID);
vcEVT_AUFLAGIDNEU := LTRIM (RTRIM (SUBSTR (vcEVT_AUFLAGID, nStartPos, nPosSep - 1)));--EVT_AUFLAGIDNEU mit Teilstring befüllen

--dbms_output.put_line (vcEVT_AUFLAGIDNEU);
INSERT INTO MSD_UMSCHL (RECNO,
SAP_AUFTRART,
SAP_VBA,
SAP_POSART,
SAP_PREISGR,
SAP_PREISSCHL,
SAP_LIEFERART,
SAP_BEZPER,
EVT_AUFLAGID,
EVT_LIEFERID,
EVT_LPOSTID,
EVT_RABSATZ,
EVT_ZALART,
EVT_LANDID,
EVT_OBJID)
VALUES (nRECNO, vcSAP_AUFTRART,
vcSAP_VBA,
vcSAP_POSART,
vcSAP_PREISGR,
vcSAP_PREISSCHL,
vcSAP_LIEFERART,
vcSAP_BEZPER,
vcEVT_AUFLAGIDNEU,
vcEVT_LIEFERID,
vcEVT_LPOSTID,
vcEVT_RABSATZ,
vcEVT_ZALART,
vcEVT_LANDID,
vcEVT_OBJID); --separate Zeile in Tabelle mit Teilstring im Feld EVT_AUFLAGID einfügen

nStartPos := nPosSep + 1;--Startposition auf Position des Kommas + 1 Zeichen setzen
-- DBMS_OUTPUT.put_line (nStart);
END IF;
END LOOP;

COMMIT;
CLOSE CUR1;

END;

Leider habe ich den Syntax für die WHILE-Schleife anscheinend nicht drauf...es kommt nämlich eine Fehlermeldung beim ausführen.

Vielleicht kann da noch jemand helfen?

Danke & Gruß,
Achim
 
Schau mal ob das zum Ziel führt, aber

ACHTUNG: NICHT AUF EINEM PRODUKTIV SYSTEM AUSFÜHREN BEVOR ES AUSREICHEND UND VORALLEM ERFOLGREICH GETESTET WURDE!

Ich übernehme keinerlei Haftung für entstandene Schäden/Ersatzansprüche. Die Verwendung erfolgt auf eigene Gefahr.

Code:
DECLARE nStartPos NUMBER; nPosSep NUMBER; vcEVT_AUFLAGIDNEU MSD_UMSCHL.EVT_AUFLAGID%TYPE;
BEGIN
  FOR item IN (SELECT RECNO,SAP_AUFTRART,SAP_VBA,SAP_POSART,SAP_PREISGR,SAP_PREISSCHL,SAP_LIEFERART,SAP_BEZPER,EVT_AUFLAGID,
    EVT_LIEFERID,EVT_LPOSTID,EVT_RABSATZ,EVT_ZALART,EVT_LANDID,EVT_OBJID FROM vs_msd_umschl) LOOP
    nStartPos := 1; --Startposition im String
    nPosSep := INSTR(item.EVT_AUFLAGID,',',nStartPos); --Position des ersten Kommas im String
    WHILE (nPosSep > 0) LOOP
      nPosSep := INSTR(item.EVT_AUFLAGID,',',nStartPos);--nächstes Komma im String ab StartPos
      vcEVT_AUFLAGIDNEU := LTRIM(RTRIM(SUBSTR(item.EVT_AUFLAGID,nStartPos,nPosSep-1))); --EVT_AUFLAGIDNEU mit Teilstring befüllen
      --separate Zeile in Tabelle mit Teilstring im Feld EVT_AUFLAGID einfügen
      INSERT INTO MSD_UMSCHL
      (
        RECNO,SAP_AUFTRART,SAP_VBA,SAP_POSART,SAP_PREISGR,SAP_PREISSCHL,SAP_LIEFERART,SAP_BEZPER,
        EVT_AUFLAGID,EVT_LIEFERID,EVT_LPOSTID,EVT_RABSATZ,EVT_ZALART,EVT_LANDID,EVT_OBJID
      )
      VALUES
      (
        item.RECNO,item.SAP_AUFTRART,item.SAP_VBA,item.SAP_POSART,item.SAP_PREISGR,item.SAP_PREISSCHL,item.SAP_LIEFERART,item.SAP_BEZPER,
        vcEVT_AUFLAGIDNEU,item.EVT_LIEFERID,item.EVT_LPOSTID,item.EVT_RABSATZ,item.EVT_ZALART,item.EVT_LANDID,item.EVT_OBJID
      );
      nStartPos := nPosSep + 1;
    END LOOP;
  END LOOP;
END;
/
 
Zurück
Oben