none
Datenbanken abfragen mit @variable als DB-Name RRS feed

  • Frage

  • Hallo,

    ich muss alle Datenbanken durchgehen und einen Wert aus einer Tabelle sowie die Grösse der Datenbank abfragen. Dafür habe ich an einen CURSOR gedacht und diesen mal angelegt, nur schaffe ich es nicht mit dem gefundenen Namen der Datenbank diese dann abzufragen.

    Der Cursor:

    use [master]
    
    
    
    -- Variable für Datenbankname
    
    declare @dbname as varchar(255)
    
    -- Cursor definieren
    
    declare dbnames cursor for
    
    select name from sysdatabases where status = '1073807369'
    
    -- Cursor öffnen
    
    open dbnames
    
    -- Cursor-Ergebnisse durchgehen
    
    fetch next from dbnames
    
    into @dbname
    
    -- begin/end so lange es Ergebnisse gibt
    
    while @@FETCH_STATUS = 0
    
    begin
    
    	print @dbname
    
    	declare @engname as varchar(255)
    
    	
    
    	
    
    	-- nächstes Ergebnis
    
    	fetch next from dbnames
    
    	into @dbname
    
    end
    
    
    
    -- Cursor schliessen und entfernen
    
    close dbnames
    
    deallocate dbnames
    
    
    
    

    Anstelle des Print würde ich dann gerne den SELECT UserName from @dbname.KnownUser abfragen, aber scheinbar kann ich keine Variable nutzem um eine Datenbank damit ansprechen zu können.

    Was habe ich übersehen? Muss ich anderst vorgehen um das zu erreichen?

    Weitere wäre eine Frage wichtig, wie kann ich feststellen das der Datenbankname einer GUID entspricht? Derzeit frage ich den Status ab da es noch keine andere Tabellen gibt, ist also gerade nicht so wichtig, aber interessant :-)

    Viele Grüsse,
    Maxi



    Mittwoch, 31. August 2011 08:11

Antworten

  • Hallo Maxi,

    Dein Cursor Skript macht nicht viel Sinnvolles, deswegen wird das schwierig
    die eigentliche Intention zu erkennen.

    Grundsätzlich gilt, dass eine Abfrage auf den aktuellen Datenbankkontext zugreift,
    wenn kein drei- (oder vier-)teiliger Bezeichner verwendet wird.
    Ein Bezeichner muss wiederum zur Übersetzungszeit feststehen.

    Wenn Du auf eine bestimmte Tabelle einer (unbekannten) abfragen willst,
    musst Du deswegen auf dynamisches SQL via sp_executeql zurückgreifen.

    Das Abfragen über mehrere Datenbanken wird dann schon trickreicher.
    Aaron Betrand hat dazu mal eine erweiterte Version der undokumentierten sp_MSforeachdb geschrieben:

    Making a more reliable and flexible sp_MSforeachdb
    Der Blog Eintrag dazu http://sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/a-more-reliable-and-more-flexible-sp-msforeachdb.aspx

    was auch zeigen sollte, dass es ziemlich scheußlich werden kann.

    Weitere Anmerkungen als Ergänzung:

    Desweiteren ist sysdatabases ab SQL Server 2005 veraltet.
    Wenn verwende die aktuellen Verwaltungssichten, zuerst wäre da sys.databases ff.
    Die Größe einer Datenbank kann man zwar auch selbst berechnen, einfacher wäre aber sp_spaceused

    Auf einen uniqueidentifier / Guid könnte man so testen:

    DECLARE @GuidTest TABLE (value sysname NULL);
    INSERT INTO @GuidTest VALUES 
    	(NULL), (''), ('abcd'),
    	('4AFCAA8D-70B1-40EE-A040-B6D16AA75E29'),
    	('A44E1469-8d5b-47ce-8780-d14a3da4a0E6'),
    	('A44E1469-8D5B-47CE-D14A3DA4A0E6');
    
    SELECT value, CASE WHEN value LIKE 
    		REPLICATE('[0-9A-Fa-f]', 8) + '-' 
    		+ REPLICATE(REPLICATE('[0-9A-Fa-f]', 4) + '-', 3)
    		+ REPLICATE('[0-9A-Fa-f]', 12)
    	THEN CAST(1 AS bit)
    	ELSE CAST(0 AS bit) END AS IsGUID 
    FROM @GuidTest;
    
    
    (Für häufigeren Einsatz könnte das als Funktion nützlich sein).

    Summa Summarum:
    Da Du vermutlich eh via VB.NET zugreifen willst:
    Damit kann es einfacher sein, die diversen String-Operationen und Tests unter einen Hut zu bringen.

    Gruß Elmar

    Mittwoch, 31. August 2011 08:58

Alle Antworten

  • Für diesen Fall ist die undokumentierte Prozedur sp_msforeachdb unter Umständen deine Lösung.

    Mittwoch, 31. August 2011 08:54
  • Hallo Maxi,

    Dein Cursor Skript macht nicht viel Sinnvolles, deswegen wird das schwierig
    die eigentliche Intention zu erkennen.

    Grundsätzlich gilt, dass eine Abfrage auf den aktuellen Datenbankkontext zugreift,
    wenn kein drei- (oder vier-)teiliger Bezeichner verwendet wird.
    Ein Bezeichner muss wiederum zur Übersetzungszeit feststehen.

    Wenn Du auf eine bestimmte Tabelle einer (unbekannten) abfragen willst,
    musst Du deswegen auf dynamisches SQL via sp_executeql zurückgreifen.

    Das Abfragen über mehrere Datenbanken wird dann schon trickreicher.
    Aaron Betrand hat dazu mal eine erweiterte Version der undokumentierten sp_MSforeachdb geschrieben:

    Making a more reliable and flexible sp_MSforeachdb
    Der Blog Eintrag dazu http://sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/a-more-reliable-and-more-flexible-sp-msforeachdb.aspx

    was auch zeigen sollte, dass es ziemlich scheußlich werden kann.

    Weitere Anmerkungen als Ergänzung:

    Desweiteren ist sysdatabases ab SQL Server 2005 veraltet.
    Wenn verwende die aktuellen Verwaltungssichten, zuerst wäre da sys.databases ff.
    Die Größe einer Datenbank kann man zwar auch selbst berechnen, einfacher wäre aber sp_spaceused

    Auf einen uniqueidentifier / Guid könnte man so testen:

    DECLARE @GuidTest TABLE (value sysname NULL);
    INSERT INTO @GuidTest VALUES 
    	(NULL), (''), ('abcd'),
    	('4AFCAA8D-70B1-40EE-A040-B6D16AA75E29'),
    	('A44E1469-8d5b-47ce-8780-d14a3da4a0E6'),
    	('A44E1469-8D5B-47CE-D14A3DA4A0E6');
    
    SELECT value, CASE WHEN value LIKE 
    		REPLICATE('[0-9A-Fa-f]', 8) + '-' 
    		+ REPLICATE(REPLICATE('[0-9A-Fa-f]', 4) + '-', 3)
    		+ REPLICATE('[0-9A-Fa-f]', 12)
    	THEN CAST(1 AS bit)
    	ELSE CAST(0 AS bit) END AS IsGUID 
    FROM @GuidTest;
    
    
    (Für häufigeren Einsatz könnte das als Funktion nützlich sein).

    Summa Summarum:
    Da Du vermutlich eh via VB.NET zugreifen willst:
    Damit kann es einfacher sein, die diversen String-Operationen und Tests unter einen Hut zu bringen.

    Gruß Elmar

    Mittwoch, 31. August 2011 08:58
  • Hallo MaxiTesch,

    Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat.
    Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.

    Grüße,
    Robert

    Freitag, 9. September 2011 13:07
    Moderator