none
SQL-Server 2008 / Dynamic SQL kein Datenbankwechsel mit USE RRS feed

  • 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

    Dienstag, 10. Juli 2018 06:13

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


    Dienstag, 10. Juli 2018 07:09
    Beantworter
  • 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.


    Dienstag, 10. Juli 2018 07:25