Fragensteller
SQL-Server 2008 / Dynamic SQL kein Datenbankwechsel mit USE

Frage
-
Hallo,
ich muss für eine User-Migration in allen meinen Datenbanken auf einer SQL-Server-Instanz User klonen.
Nun habe ich das das Probelm das die USE-Anweisung in Dynamic SQL scheinbar nicht funktioniert.SET @strSQL = N'USE ' + QUOTENAME(@DBname) --Datenbak auswählen EXEC sp_executesql @strSQL;
In einen Thread habe ich folgenden gefunden:
set @sql = 'use ' + quotename(@new_db_name) + '; disable trigger t1;' exec (@sql)
Das funktioniert auch nicht allerdings auch nicht, da bekomme ich eine Fehlermeldung.
Mein Problem ist das ich folgende Anweisung in der jeweiligen Datenbankumgebung ausführen muss:
SET @roleName = QUOTENAME(USER_NAME(CAST(@roleID AS INTEGER)))
Das funktioniert aber nur in der jeweils zur Rollen-ID gehörenden Datenbank.
Den Rollennamen benötige ich um dem geklonten User die jeweiligen Rechte zuzuordnen.Hat jemand eine Lösung dafür oder gibt es einen besseren Lösungsansatz?
Gruß
cheapy
Alle Antworten
-
Ich glaube, dass ich schon mal auf meinen Artikel hingewiesen habe: Umzug in eine neue Domäne
Dort mache ich es so, dass ich zuerst die Daten in einer Tabelle sammle. Danach erstelle ich mir aus den gesammelten Daten ein Skript um die Datenbank-Kontexte zu wechseln und die User entsprechend zu ändern. (A01a_User_Mapping)
Ich verwende dazu die undokumentierte Prozedur sp_MSforeachdb, welche den Datenbanknamen als Parameter übergibt. Daher habe ich dann nur ein
use ? ; WITH perms_cte(principa ...
in meinem dynamischem Statement.
Ansonsten solltest Du beachten, dass eine Änderung des Datenbank-Kontextes in dynamischem SQL gekapselt abläuft und für den darum herum liegenden Batch keine Bedeutung hat. Du müsstest also alle Statements im gleichen dynamischen Statement zusammen laufen lassen.
Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu
- Bearbeitet Christoph MuthmannEditor Dienstag, 10. Juli 2018 07:10
-
OK, das schaue ich mir dann noch einmal an.
Für die Problematik mit dem Rollennamen habe ich so eine Umgehung gefunden:DECLARE @strSQL nvarchar(2000) DECLARE @DBname nvarchar(100) DECLARE @OldLogin nvarchar(100) DECLARE @roleID int DECLARE @roleName nvarchar(100) SET @DBname =N'My_Database' SET @OldLogin = N'OldDomain\max.mustermann' SET @strSQL = N'USE ' + QUOTENAME(@DBname) + N'; DECLARE userRoles CURSOR SCROLL GLOBAL READ_ONLY FOR SELECT rm.role_principal_id AS rolename, QUOTENAME(USER_NAME(rm.role_principal_id)) FROM sys.syslogins INNER JOIN ' + QUOTENAME(@DBname) + N'.sys.sysusers AS su ON sys.syslogins.sid = su.sid INNER JOIN ' + QUOTENAME(@DBname) + N'.sys.database_role_members AS rm ON su.uid = rm.member_principal_id WHERE (sys.syslogins.name = N''' + @OldLogin + ''');' EXEC sp_executesql @strSQL PRINT CURSOR_STATUS('global','userRoles') OPEN userRoles FETCH NEXT FROM userRoles INTO @roleID, @roleName Print @@FETCH_STATUS PRINT @roleID PRINT @roleName CLOSE userRoles; DEALLOCATE userRoles;
Ist sicher nicht wer Weißheit letzter Schluss aber zumindenst erlaubt mir der Globale Cursor den Zugriff auf die benötigten Daten.
- Bearbeitet Cheaptrick_la Mittwoch, 11. Juli 2018 11:54