mtb4ever
Goto Top

Oracle SQL: Benutzernamen in mehreren dynamischen Tabellen ersetzen

Guten Morgen,
ich habe folgendes Szenario und zwar habe ich verschiedene Tabellen, die auch teilweise einen generierten Namen haben, in denen Benutzernamen drin stehen. Diese sollen mit anonymen Namen (z.B. User 1) ersetzt werden und dies soll in jeder Tabelle gleich passieren, also ein "Max M." wird in Tabelle 1 zu "User 1" und auch in Tabelle X usw.

Da es keine Benutzerliste gibt, welche Benutzer alles vorhanden sein können, hatte ich mir überlegt erst die vorhanden Benutzer auszulesen und in einer Zwischentabelle zu speichern.
Dazu habe ich ein select gebaut welches verschiedene select anfragen zusammen baut mit allen Tabellen und Spalten wo die Benutzer enthalten sind

select 
 'SELECT '||table_name||'.'||column_name || ' as Name from '|| table_name ||' Group by '|| column_name || ';'   
 from user_tab_columns where (column_name like '%USERNAME%') AND data_type LIKE '%CHAR%';  

Soweit bin ich schon mal, jetzt zu den Stellen wo ich Unterstützung nett finden würde.

Da dieses select viele andere Selects generiert habe ich mir gedacht, das man das in einer Art Schleife durchlaufen könnte um die Benutzernamen in einer Zwischentabelle zu speichern.

Aus den Gefunden Benutzer soll dann aus "Benutzer A" der neue Benutzer "User 01", aus "Benutzer B" der neue Benutzer "User 02" usw werden. Und diese Benutzer sollen dann in allen Tabellen ersetzt werden.

Da ich noch nicht viel Erfahrung mit Schleifen habe wäre es nett wenn mir einer unter die Arme greifen könnte.


Verwenden tue ich eine Oracle Datenbank.

Content-ID: 1869951978

Url: https://administrator.de/contentid/1869951978

Ausgedruckt am: 25.11.2024 um 15:11 Uhr

em-pie
em-pie 09.02.2022 um 09:48:27 Uhr
Goto Top
Moin,

perse würde ich die Anonymisierung via ROW_NUMBER() realisieren, in Kombination mit CONCAT.

Dann hast du erstmal alle User der neuen Tabelle in Spalte username und fügst (später) wie ROW_NUMBER in spalte anonymous via CONCAT dann ein CONCAT('USER', RIGHT(CONCAT('000', ROW_NUMBER()), 3)) hinzu.

Gruß
em-pie
ukulele-7
ukulele-7 09.02.2022 um 11:30:48 Uhr
Goto Top
Ich habe noch nie was mit Oracle gemacht, in MSSQL würde ich es aber auch so machen.

Schleife:
Es gibt WHILE-Schleifen aber ich würde sagen besser wäre ein Cursor, dein Select gibt ja schon die beste Basis dafür. Der Cursor befüllt dann eine Variable mit dem Code, den kannst du dann mit EXEC() nacheinander ausführen. Natürlich müsste man den noch entsprechend umgestalten.

Code:
Ich würde innerhalb des Cursors dann erstmal ein Statement machen das alle Usernamen, die in der zentralen Tabelle noch nicht existieren, da rein schreibt und in dieser zentralen Tabelle einen Alias generieren, siehe @em-pie .

Dann im Anschluss einfach ein Update auf der vorhandenen Tabelle, das läßt sich dann jederzeit wieder rückgängig machen.
MTB4ever
MTB4ever 09.02.2022 um 16:11:56 Uhr
Goto Top
Ein Stück weiter bin ich schon gekommen. Es werden jetzt alle Benutzernamen in die Tabelle Benutzer geschrieben.
CREATE TABLE Benutzer
( BenutzerName varchar2(50),
NeuerName varchar2(50)
);
BEGIN
  FOR item IN (select 
 'INSERT INTO Benutzer (BenutzerName) SELECT '||table_name||'.'||column_name || ' as Name from '|| table_name ||' Group by '|| column_name || '' as x  
 from user_tab_columns where (column_name like '%USER%') AND data_type LIKE '%CHAR%' ) LOOP  
   execute immediate item.x;
  END LOOP;
END;
/
delete from benutzer a where rowid > (select min(rowid) from benutzer b where b.benutzername=a.benutzername);
Update Benutzer set neuername= 'User ' || rownum;  
select * from Benutzer;

Wenn ich jetzt allerdings ein Update Skript zusammen baue kennt dieses die Tabelle bzw die Spalte Benutzer name nicht.

Das Update Skript baue ich so zusammen

select 'UPDATE '||table_name||' SET '||column_name || '= Benutzer.NeuerName WHERE '|| table_name ||'.'|| column_name || ' = Benutzer.BenutzerName' as x  
 from user_tab_columns where (column_name like '%USER%') AND data_type LIKE '%CHAR%'   

Daraus entsteht dann so ein Update Bwfehl
UPDATE Tabelle1 SET Username= Benutzer.NeuerName WHERE Tabelle1.Username = Benutzer.BenutzerName;

Hat jemand eine Idee dazu?
em-pie
em-pie 09.02.2022 um 18:19:11 Uhr
Goto Top
ich bin jetzt auch kein ORACLE-User, aber du musst doch die Tabelle Benutzer für das Update Joinen. das ist zumindest bei MS SQL der Fall.
Woher soll er denn wissen, wie das Mapping aussieht.

Hier wäre eine Hilfe dazu:
https://stackoverflow.com/questions/2446764/update-statement-with-inner- ...
ukulele-7
Lösung ukulele-7 09.02.2022 um 23:12:51 Uhr
Goto Top
Etwa so:
UPDATE Tabelle1 SET Tabelle1.Username = Benutzer.NeuerName FROM Tabelle1 INNER JOIN Benutzer ON Tabelle1.Username = Benutzer.AlterName;