Tagi na forum.

Windows 14206 SQL Server 2132
sieci 6796 Windows XP 1922
SQL 6578 Outlook 1838
SBS 3868 Uprawnienia 1777
Windows 2003 2781 IIS 1636
Windows Server 2588 Office 1516
DNS 2315 Skrypt 1499

pokaż wszystkie tagi na forum

Pętla do odpytania wielu baz

schul 2012-02-21 08:23:58
0
avatar
 
 

Mam bazę konfiguracyjną zawierającą nazwy wszystkich baz, które chciałbym odpytać. Bazy z danymi mają identyczną strukturę. W jaki sposób mógłbym zbudować pętlę do odpytania wszystkich baz zawartych w bazie konfiguracyjnej (baza konfiguracyjna zawiera kolumnę z nazwami baz i indeks, który jest ułożony nie po kolei, i nie zaczyna się od jedynki).

Dziękuję,

Przemek


tagi: SQL


UpdateDEV  2012-02-21 08:50:10 #1
0
avatar
 
 

W przypadku gdy bazy znajduja sie na tym samym serwerze uzyj nazwy trzy czesciowej.

np SELECT * FROM baza.dbo.tabela.

Jezeli bazy znajduja sie na roznych serwerach to podlinkuj je i wtedy zapytanie bedzie mialo nastepujaca postac

SELECT * FROM [link].baza.dbo.tabela


schul  2012-02-21 09:10:08 #1.1
0
avatar
 
 

Tak, o tym pamiętam, kwestia pętli co to przeleci się po wszystkich bazach...


Edytowano 1 raz. Ostatnio 2012-02-21 09:17:20 przez schul.
Kirdahaa  2012-02-21 10:52:45 #2
0
avatar
 
 

Możesz użyć zwykłego kursora, przykład:

 

DECLARE 
   @DBname SYSNAME, 
   @sql NVARCHAR(max)

DECLARE cDB CURSOR FAST_FORWARD READ_ONLY
  FOR SELECT nazwa FROM baza_konfiguracyjna
 
OPEN cDB
FETCH cDB INTO @DBname
WHILE @@Fetch_Status = 0 
  BEGIN  
	SET @sql = 'SELECT * FROM ['+@DBname+'].sys.tables'
	EXEC (@sql)
    FETCH cDB INTO @DBname
  END
CLOSE cDB
DEALLOCATE cDB
 

schul  2012-02-23 20:36:58 #2.1
0
avatar
 
 

Odpaliłem i przy ok. 50-ej bazie wyskoczył mi błąd: "An error occurred while executing batch. Error message is: Exception of type 'System.OutOfMemoryException' was thrown." Skrypt jest odpalany na 2008 R2 Express. Jak temu zaradzić?


schul  2012-02-24 09:28:04 #2.2
0
avatar
 
 

Ok, uporałem się - wyniki jako tekst lub do pliku i jest ok. Pozostały mi dwa pytania: 

  • Jak z tej pętelki zrobić UNION tak by wyniki zostały zwrócone do jednej tabeli?
  • W jaki sposób wstawić nazwę bazy jako kolumnę tabeli?

vezdohan  2012-02-24 10:54:26 #2.2.1
0
avatar
 
 

Użyjmy rozwiązania kolegi Kidrahaa jako bazy.

DECLARE
   @DBname SYSNAME, 
   @sql NVARCHAR(max)
CREATE TABLE wyniki (id bigint identity(1,1),
				  nazwa_bazy SYSNAME,
				  nazwa_tabeli SYSNAME)
				  
DECLARE cDB CURSOR FAST_FORWARD READ_ONLY
  FOR SELECT master.sys.databases.name FROM master.sys.databases
  
OPEN cDB
FETCH cDB INTO @DBname
WHILE @@Fetch_Status = 0 
  BEGIN 
    SET @sql = 'INSERT INTO wyniki(nazwa_bazy,nazwa_tabeli)
    SELECT '''+@DBname+''', t.name FROM ['+@DBname+'].sys.tables t'
    EXEC (@sql)
    FETCH cDB INTO @DBname
  END
CLOSE cDB
DEALLOCATE cDB

select * from wyniki

Nie mam bazy konfiguracyjnej wiec biorę wszystkie.

Czyli:

Jak z tej pętelki zrobić UNION tak by wyniki zostały zwrócone do jednej tabeli?

Nie robić kolejne wywołanie dopisuje

W jaki sposób wstawić nazwę bazy jako kolumnę tabeli?

Jako kawałek dynamicznego stringu.


vezdohan  2012-02-21 10:54:09 #3
0
avatar
 
 

Dwa sposoby:

1. EXEC sp_MSForEachDB 'IF ''[?]'' NOT IN (''[master]'', ''[model]'', ''[msdb]'', ''[tempdb]'') select ''[?]'',count(*) from [?].dbo.sysobjects'

Oczywiście to NOT IN musisz zbudować na podstawie swojej bazy.

2. Normalny kursor i dynamiczny sql


Kirdahaa  2012-02-21 11:11:10 #4
0
avatar
 
 

Z sp_MSforeachdb bym uważał, komenda przyjmuje tylko 2000 znaków, chyba że użyjesz dodatkowych parametrów 

@command2 nvarchar(2000), @command3 nvarchar(2000), @precommand nvarchar(2000), @postcommand nvarchar(2000)


Udziel odpowiedzi

avatar
Treść wpisu:

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.

Idź na górę strony