Beim Umsetzen von logischen Systemnamen im SAP mittels der Transaktion BLDS kann es trotz Indizes vorkommen, dass ein Lauf einfach zu lange benötigt – oder im Extremfall (gerade erlebt) der Rückgabewert der Menge der umzusetzenden logoischen Systemnamen so groß ist, dass die Variable die Zahl nicht aufnehmen kann und die BLDS mit einem Kurzdump einfach aussteigt. Es muss also nicht immer an der Größe der Datenbank oder der Systemperformance liegen wenn die BLDS streikt. Das komplette Vorgehen kann man extrem beschleunigen wenn man an der BDLS Funktionalität vorbei direkt auf der Datenbank die Umsetzung der Tabelle vorgenommen wird. Im sqlplus kommt man jedoch mit einem einfachen Update Statement nicht schneller als die BDLS selbst ans Ziel. Das Zaubertool der Wahl heißt in diesem Fall CTS – create table as.
Das Vorgehen ist recht einfach aber sehr effektiv und schnell. Man teilt dem Oracle lediglich mit, dass man eine neue Tabelle erstellen möchte und gibt die Referenzen auf eine bestehende Tabelle an. Den Rest erledigt das System selbst – parallelisiert und sehr schnell. Das Updaten einer Tabelle mit mehreren Milliarden Einträgen und einer größe von mehr als einem TB kann schon mal Tage benötigen. Mit dem CTS hat man die Tabelle in wenigen Stunden neu aufgebaut und auch gleich die gewünschten Feldinhalte verändert.
Das Vorgehen sieht inetwa so aus:
1) Ermitteln der Quelltabelle mit den Feldnamen für die logischen Systeme
2) Neuaufbau der Tabelle
3) Nacharbeiten an der Tabelle
4) Umbennen/Ersetzen der Tabellen
5) Neuaufbau der Indizes zu den Tabellen
6) Löschen der alten Tabelle
Ermitteln der Quelltabelle mit den Feldnamen für die logischen Systeme:
Aus den BDLS Protokollen weiß man jetzt zum Beispiel, dass im BW eine Tabelle mit über 2 MRD Einträgen existiert, die umgesetzt werden soll:
„/BIC/ZPWE“ mit den Feldern LOGSYS und AWSYS, die die logischen Systemnamen beinhalten und umgesetzt werden sollen.
Neuaufbau der Tabelle:
Das Statement zum Neuaufbau könnte dann so aussehen:
CREATE TABLE PWE."/BIC/ZPWE_TEMP" PARALLEL NOLOGGING TABLESPACE PSAPBWH AS (SELECT REQUEST, RECORD, DATAPAKID, CASE LOGSYS WHEN 'PBW100' THEN 'DBW100' WHEN 'PERP100' THEN 'DERP100' ElSE LOGSYS END LOGSYS, "/BIC/ZCOOCLNT", "/BIC/ZCOAUTOM", CASE AWSYS WHEN 'PBW100' THEN 'DBW100' WHEN 'PERP100' THEN 'DERP100' ElSE AWSYS END AWSYS, WBS_ELEMT FROM PWE."/BIC/ZPWE"); commit;
Mittels des Statements wird die Tabelle „/BIC/ZPWE_TEMP“ neu aufgebaut und alle Feldinhalte für LOGSYS oder AWSYS entsprechend von PBW100 auf DBW100 bzw. von PERP100 auf DERP100 umgesetzt. Kommt in den Feldern keiner der genannten Einträge vor so wird keine Änderung vorgenommenb und der vorhandene Eintrag genutzt.F
Nacharbeiten an der Tabelle:
Achtung, bei der Umsetzung von Feldinhalten beim CTS werden die Constraints entfernt. Diese müssen hinterher wieder nachträglich gesetzt werden!
SQL> descr PWE."/BIC/ZPWE" Name Null? Type --------------------------------------------------------------------------------------------------------- REQUEST NOT NULL VARCHAR2(90) RECORD NOT NULL VARCHAR2(18) DATAPAKID NOT NULL VARCHAR2(18) LOGSYS NOT NULL VARCHAR2(30) /BIC/ZCOOCLNT NOT NULL VARCHAR2(30) /BIC/ZCOAUTOM NOT NULL VARCHAR2(24) AWSYS NOT NULL VARCHAR2(30) WBS_ELEMT NOT NULL VARCHAR2(40) SQL> descr PWE."/BIC/ZPWE_TEMP" Name Null? Type --------------------------------------------------------------------------------------------------------- REQUEST NOT NULL VARCHAR2(90) RECORD NOT NULL VARCHAR2(18) DATAPAKID NOT NULL VARCHAR2(18) LOGSYS VARCHAR2(30) /BIC/ZCOOCLNT NOT NULL VARCHAR2(30) /BIC/ZCOAUTOM NOT NULL VARCHAR2(24) AWSYS VARCHAR2(30) WBS_ELEMT NOT NULL VARCHAR2(40) SQL>
Das Wiederherstellen der NOT NULL Bedinung passiert so (benötigt aber unter Umständen auch wieder viel Zeit!):
ALTER TABLE PWE."/BIC/ZPWE_TEMP" modify LOGSYS not null; ALTER TABLE PWE."/BIC/ZPWE_TEMP" modify AWSYS not null; commit;
Umbennen/Ersetzen der Tabellen:
Die originale Tabelle „PWE.“/BIC/ZPWE“ wird zunächst umbeannt, sie wird erst gelöscht wenn die Tests komplett erfolgreich waren und sichergestellt ist, dass der Inhalt der neu aufgebauten Tabelle wirklich der zu erwartende Inhalt ist. Vor dem Umbennen werden noch die Indizes gedropt. Die Definitionen sind im SAP hinterlegt, die Indizes werden über die Transaktion SE14 im Hintergrund wieder neu aufgebaut (langsam) oder direkt über das Oracle.
Die Indizes kann man sich zum Beispiel so anzeigen lassen:
SQL> select INDEX_NAME,INDEX_TYPE, TABLE_NAME from dba_indexes where TABLE_NAME = '/BIC/ZPWE'; INDEX_NAME INDEX_TYPE TABLE_NAME ------------------------------ --------------------------- ------------------------------ /BIC/ZPWE~BDLS NORMAL /BIC/ZPWE /BIC/ZPWE~BDLS2 NORMAL /BIC/ZPWE /BIC/ZPWE~0 NORMAL /BIC/ZPWE SQL>
Um sich die Statements für das Generieren der Indizes anzeigen zu lassen kann man sich des DBMS_METADATA Packages bedienen:
SQL> set timi on head off long 5000 pagesize 0 SQL> select DBMS_METADATA.GET_DDL('INDEX','/BIC/ZPWE~BDLS') DDL from dual; CREATE INDEX "PWE"."/BIC/ZPWE~BDLS" ON "PWE"."/BIC/ZPWE" ("LOGSYS") PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS COMPRESS 1 NOLOGGING STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "PSAPPWE" Elapsed: 00:00:00.02 SQL>
Neuaufbau der Indizes zu den Tabellen:
Das Erzeugen über Oracle mittels parallelem Aufbau und NOLOGGING geht wesentlich schneller als über die TX SE14! Daher auf jeden Fall die Schlüsselwörter „NOLOGGING PARALLEL COMPUTE STATISTICS“ dem Statement hinzufügen wenn sie nicht vorhanden sein sollten. Wenn man möchte kann man den Index auch gleich noch komprimiert anlegen. Das sollte lizenztechnisch beiden meisten Kunden möglich sein. Hierzu einfach das Schlüsselwort COMPRESS 1 mit angeben. Und nicht vergessen: nach Abschluss des Indexaufbau die Parallelität wieder deaktivieren:
ALTER INDEX "/BIC/ZPWE~BDLS" NOPARALLEL;
Die bestehenden Indizes der original Tabelle werden auf Oracle-Ebene einfach gedropt, sobald man weiß wie man die neuen anzulegen hat und im Anschluss dann neu angelegt:
drop index /BIC/ZPWE~BDLS drop index /BIC/ZPWE~BDLS2 drop index /BIC/ZPWE~0 commit;
Jetzt die Indiezes zum Beispiel wie oben über das Meta Package ermittelt wieder anlegen:
CREATE INDEX "PWE"."/BIC/ZPWE~BDLS" ON "PWE"."/BIC/ZPWE" ("LOGSYS") PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS COMPRESS 1 NOLOGGING PARALLEL STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "PSAPPWE"; ALTER INDEX "PWE"."/BIC/ZPWE~BDLS" NOPARALLEL;
Anschließend werden die Tabellen umebannt:
rename PWE."/BIC/ZPWE" to PWE."/BIC/ZPWE_ORIG"; rename PWE."/BIC/ZPWE_TEMP" to PWE."/BIC/ZPWE"; commit;
Löschen der alten Tabelle:
Wenn alles funktioniert kann die originale Tabelle geslöscht werden.
drop table PWE."/BIC/ZPWE_ORIG"; commit;
Wenn man häufiger Systemkopien in den gleichen Umegebungen vornimmt macht es durchaus Sinn die einzelen Tasks in kleinere SQL Scripte aufzuteilen und diese dann über ein Wrapperscript auszuführen. Hierbei sollte man jedoch unbedingt die SQL Funktion „whenever sqlerror exit sql.sqlcode“ nutzen.