Spis treści:

Kategoria:SQL Server


Dodawanie kolumny w SQL Server tylko wtedy, gdy nie istnieje

Wyobraźmy sobie następującą sytuację: musimy zmodyfikować strukturę tabeli w SQL Server, a dokładniej - dodać do niej kolumnę. Przygotowujemy sobie prosty skrypt, który nam takie zadanie wykona:

ALTER TABLE MyTable ADD MyColumn int

Proste i przejrzyste, więc nie wymaga komentarza.

Kolejną sytuacją do wyobrażenia sobie będzie kilku klientów, z których każdy ma różną wersję bazy. Co jest w naszym przypadku istotne - niektórzy klienci mają już częściowo zaktualizowaną bazę i mają kolumnę MyColumn w tabeli MyTable, natomiast inni klienci takiej kolumny nie mają. Co wtedy zrobić? Prosty skrypt nie wystarczy. Gdy klient danej kolumny nie ma, skrypt zadziała właściwie. Gdy ma, skrypt zakończy się błędem i wielce prawdopodobne jest, że przerwie jednocześnie całą procedurę aktualizacji. Co wtedy zrobić? Jedno z rozwiązań pokazane jest poniżej:

IF NOT EXISTS (SELECTFROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='dbo' AND TABLE_NAME = 'MyTable' AND COLUMN_NAME = 'MyColumn')
BEGIN
   ALTER TABLE dbo.RollupTable ADD Aaa int
END

Można to wszystko jeszcze bardziej udoskonalić i napisać sobie procedurę składowaną. Istnieje wiele możliwości napisania takiego skryptu. Najczęściej wykorzystywaną przeze mnie wersją jest ta zaprezentowana poniżej:

CREATE PROCEDURE dbo.AddColumn
@table nvarchar(128),
@column nvarchar(128)
AS
DECLARE @iDot int
SELECT @iDot=CHARINDEX('.', @table)
DECLARE @sch nvarchar(64) = SUBSTRING(@table, 1, @iDot-1)
DECLARE @tab nvarchar(64) = SUBSTRING(@table, @iDot+1, 128)

DECLARE @iSeparator int
SELECT @iSeparator=CHARINDEX(' ', @column)
DECLARE @col nvarchar(64) = SUBSTRING(@column, 1, @iSeparator-1)
DECLARE @type nvarchar(64) = SUBSTRING(@column, @iSeparator+1, 128)

DECLARE @sql nvarchar(1024) =
'IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS '+
'WHERE TABLE_SCHEMA='''+@sch+''''+
' AND TABLE_NAME = '''+@tab+''''+
' AND COLUMN_NAME = '''+@col+''') '+
'BEGIN'+
' ALTER TABLE '+@sch+'.'+@tab+' ADD '+@col+' '+@type+' '+
'END'

EXEC sp_sqlexec @sql

Pierwszym parametrem jest nazwa tabeli wraz ze schematem ('dbo.MyTable'). Drugi parametr to nazwa kolumny oraz typ kolumny (MyColumn int). Jak można zauważyć, pola w pierwszym parametrze oddzielone są kropką (w stylu SQL Server), natomiast pola w drugim parametrze oddzielone są spacją (też na wzór instrukcji SQL MyColumn int). Można to rozdzielić na więcej parametrów, ale taka wersja wydała mi się najbardziej przyjazna i intuicyjna. Należy przy tym pamiętać, że procedura zakończy się błędem w przypadku nieprawidłowych argumentów. Jeżeli podamy nazwę tabeli bez przestrzeni (czyli MyTable zamiast dbo.Table) lub nazwa kolumny w drugim parametrze będzie zawierała spację ('[My Column] int') to nie oczekujmy właściwych rezultatów. Da się to obejść, ale czasami po prostu nie warto. Wystarczy mieć świadomość tych konsekwencji i w takich kontrowersyjnych przypadkach z tej procedury nie korzystać. Doświadczenie pokazuje, że taka wersja nadaje się do zdecydowanej większości zadań.

Wywołanie tej procedury jest bajecznie proste. Może to być na przykład taka instrukcja:

EXEC AddColumn 'dbo.RollupTable''Aaa int'

Kategoria:SQL Server

, 2013-12-20

Brak komentarzy - bądź pierwszy

Dodaj komentarz
Wyślij
Ostatnie komentarze
Dzieki za rozjasnienie zagadnienia upsert. wlasnie sie ucze programowania :).
Co się stanie gdy spróbuję wyszukać:
SELECT * FROM NV_Airport WHERE Code='SVO'
SELECT * FROM V_Airport WHERE Code=N'SVO'
(odwrotnie są te N-ki)
Będzie konwersja czy nie znajdzie żadnego rekordu?