20

Niedawno mieliśmy problemy na naszym serwerze bazy danych i po długich staraniach postanowiono zmienić serwer bazy danych. Udało nam się przywrócić bazę danych na innym serwerze, zmienić ciąg połączenia itd. Wszystko przebiegało zgodnie z planem, dopóki nie spróbowaliśmy uzyskać dostępu do strony internetowej z przeglądarki internetowej.Jak zmienić schemat wszystkich tabel, widoków i procedur przechowywanych w MSSQL

Zaczęliśmy otrzymywać błędy dotyczące nieodnalezienia obiektów bazy danych. Później dowiedzieliśmy się, że pojawił się on w wyniku zmodyfikowania nazwy schematu. Ponieważ w bazie danych Kentico znajdują się setki obiektów bazy danych (tabele, widoki i procedury składowane), nie jest możliwe ręczne ich zmienianie, jeden po drugim. Czy istnieje praktyczny sposób robienia tego?

+0

Czy na pewno po prostu nie ustawiłeś domyślnie domyślnego schematu użytkownika? –

+0

Pytanie ma prawie dwa lata, ale o ile pamiętam, nie było ono związane z domyślnym schematem użytkownika. –

+0

Oh! z jakiegoś powodu pojawił się na szczycie listy! –

Odpowiedz

74

Tak, jest to możliwe.

Aby zmienić schemat obiektu bazy danych należy uruchomić następujący skrypt SQL:

ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.ObjectName 

Gdzie ObjectName może być nazwą tabeli, widoku lub procedury przechowywanej. Wydaje się, że problemem jest uzyskanie listy wszystkich obiektów bazy danych o podanej nazwie shcema. Na szczęście istnieje tabela systemowa o nazwie sys.Objects, która przechowuje wszystkie obiekty bazy danych. Następująca kwerenda wygeneruje wszystkie potrzebne skrypty SQL do wykonania tego zadania:

SELECT 'ALTER SCHEMA NewSchemaName TRANSFER [' + SysSchemas.Name + '].[' + DbObjects.Name + '];' 
FROM sys.Objects DbObjects 
INNER JOIN sys.Schemas SysSchemas ON DbObjects.schema_id = SysSchemas.schema_id 
WHERE SysSchemas.Name = 'OldSchemaName' 
AND (DbObjects.Type IN ('U', 'P', 'V')) 

Gdzie typu „U” oznacza tabele użytkowników, „V” oznacza widoki i „P” oznacza procedur przechowywanych.

Uruchomienie powyższego skryptu wygeneruje polecenia SQL potrzebne do przeniesienia obiektów z jednego schematu do innego. Coś takiego:

ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.CONTENT_KBArticle; 
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.Proc_Analytics_Statistics_Delete; 
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.Proc_CMS_QueryProvider_Select; 
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.COM_ShoppingCartSKU; 
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.CMS_WebPart; 
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.Polls_PollAnswer; 

Teraz możesz uruchomić wszystkie wygenerowane zapytania, aby zakończyć operację przesyłania.

+0

Ładne rozwiązanie. Zamiast tego użyłem "WHERE SysSchemas.Name <>" dbo "", aby wyświetlić listę wszystkich obiektów nie związanych z dbo. – Mackan

+0

Muchos Gracias. – Jono

+0

De nada, amigo.:) –

1

Dzięki za podpowiedź .. Oto moja aktualizacja do tego samego, gdzie dodałem crlf do wyprowadzenia, a także umieścić nawiasy wokół SchemaName i ObjectName, ponieważ niektóre z obiektów miały "-" w nazwie i nawiasy rozwiązały ten błąd nazywania.

SELECT 'ALTER SCHEMA NewSchemaName TRANSFER [' + SysSchemas.Name + '].[' +  DbObjects.Name + '];' 
+ CHAR(13)+ CHAR(10)+ 'GO '+ CHAR(13)+ CHAR(10) 
FROM sys.Objects DbObjects 
INNER JOIN sys.Schemas SysSchemas ON DbObjects.schema_id =  SysSchemas.schema_id 
WHERE SysSchemas.Name = 'OldSchemaName' 
AND (DbObjects.Type IN ('U', 'P', 'V')) 
3

Oto SQL wpadłem, aby przenieść wszystkie tabele w mojej bazy danych (rozłożone kilku schematów) do "" dbo schematu:

DECLARE 
    @currentSchemaName nvarchar(200), 
    @tableName nvarchar(200) 

DECLARE tableCursor CURSOR FAST_FORWARD FOR 
SELECT TABLE_SCHEMA, TABLE_NAME 
FROM information_schema.tables 
ORDER BY 1, 2 

DECLARE @SQL nvarchar(400) 

OPEN tableCursor 
FETCH NEXT FROM tableCursor INTO @currentSchemaName, @tableName 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @SQL = 'ALTER SCHEMA dbo TRANSFER ' + @currentSchemaName + '.' + @tableName 
    PRINT @SQL 

    EXEC (@SQL) 

    FETCH NEXT FROM tableCursor INTO @currentSchemaName, @tableName 
END 

CLOSE tableCursor 
DEALLOCATE tableCursor 

Uff!

0

Możesz użyć następujących scenariusza tylko kopiuj/wklej do wszystkich obiektów

UWAGA: trzeba zmienić nazwy schematu w scenariuszu!

DECLARE @OldSchema VARCHAR(200) 
DECLARE @NewSchema VARCHAR(200) 
DECLARE @SQL nvarchar(4000) 
SET @OldSchema = 'dbo' 
SET @NewSchema = 'Inf' 

DECLARE tableCursor CURSOR FAST_FORWARD FOR 
    SELECT 'ALTER SCHEMA ['+ @NewSchema +'] TRANSFER [' + SysSchemas.Name + '].[' + DbObjects.Name + '];' AS Cmd 
    FROM sys.Objects DbObjects 
    INNER JOIN sys.Schemas SysSchemas ON DbObjects.schema_id = SysSchemas.schema_id 
    WHERE SysSchemas.Name = @OldSchema 
    AND (DbObjects.Type IN ('U', 'P', 'V')) 
OPEN tableCursor 
FETCH NEXT FROM tableCursor INTO @SQL 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    PRINT @SQL 
    EXEC (@SQL) 
    FETCH NEXT FROM tableCursor INTO @SQL 
END 
CLOSE tableCursor 
DEALLOCATE tableCursor 
PRINT '*** Finished ***' 
Powiązane problemy