2014-04-08 19 views
6

Posiadamy oddzielną bazę danych dla każdego z naszych klientów. Wszystkie mają te same tabele i procedury składowane. Problem polega na tym, że kiedy musimy zaktualizować procedurę przechowywaną, musimy upewnić się, że aktualizujemy ją dla wszystkich baz danych. Oczywiście jedna procedura przechowywana w bazie danych mogła zostać przeoczona i nie zaktualizowana.Aktualizacja procedury przechowywanej w wielu bazach danych

Przyjrzałem się tworzeniu procedury składowanej w master i poprzedziłem ją sp_, a także ustawię oznaczanie obiektu jako obiektu systemowego przy użyciu sys.sp_MS_marksystemobject. Wygląda na to, że działa .... jednak ta article mówi "To rozwiązanie nie jest zalecane dla serwerów baz danych na żywo, możesz go użyć na serwerze programowania i testowania, aby przyspieszyć rozwój i testowanie."

Jeśli tak jest, jakie byłoby najlepsze rozwiązanie do produkcji?

+0

Powinieneś rzucić okiem na [Red-Gate MultiScript] (http://www.red-gate.com/products/dba/sql-multi-script/) - świetne narzędzie do wdrażania wielu skryptów do wielu serwery (lub bazy danych) naraz. Możesz zaoszczędzić ci dużo żalu! –

+0

Dzięki! to wygląda na dobre rozwiązanie. – alpha

Odpowiedz

6

Jeśli celem jest po prostu wdrożenie procedury składowanej do każdej bazy danych klientów, powinien zadziałać podobny skrypt.

-- put the entire stored procedure code in a variable 
-- have it start with "PROC" so we can easily either create or alter the 
-- procedure based on whether it already exists or not 
DECLARE @sp_code NVARCHAR(MAX) = 
' 
PROC [dbo].[usp_some_proc] AS 
SELECT DB_NAME() 
' 

-- get a list of databases to install the stored procedure to 
SELECT 
    [name] 
INTO #tbl_databases 
FROM sys.databases 
WHERE [name] LIKE 'db[_]client[0-9]' 

-- define some variables to use in the loop 
DECLARE @sql NVARCHAR(MAX); 
DECLARE @execute_sql NVARCHAR(MAX); 
DECLARE @database_name NVARCHAR(500); 

-- iterate through each database 
WHILE EXISTS (SELECT * FROM #tbl_databases) 
BEGIN 

    -- get this iteration's database 
    SELECT TOP 1 
     @database_name = [name] 
    FROM #tbl_databases 

    -- determine whether stored procedure should be created or altered 
    IF OBJECT_ID(QUOTENAME(@database_name) + '.[dbo].[usp_some_proc]') IS NULL 
     SET @sql = 'CREATE' + @sp_code; 
    ELSE 
     SET @sql = 'ALTER' + @sp_code; 

    -- define some dynamic sql to execute against the appropriate database 
    SET @execute_sql = 'EXEC ' + QUOTENAME(@database_name) + '.[dbo].[sp_executesql] @sql'; 

    -- execute the code to create/alter the procedure 
    EXEC [dbo].[sp_executesql] @execute_sql, N'@sql NVARCHAR(MAX)', @sql; 

    -- delete this database so the loop will process the next one 
    DELETE FROM #tbl_databases 
    WHERE [name] = @database_name 

END 

-- clean up :) 
DROP TABLE #tbl_databases 

Można być może coś zrobić śliskie ciągnąc definicji procedury z sys.sql_modules, ale może napotkać pewne komplikacje ze robi CREATE vs. ALTER.

+0

Dzięki! Mamy coś podobnego do tego, co tu masz. Myślę, że rozwiązanie Red Gate może być o wiele mniej smutku! – alpha

Powiązane problemy