poniedziałek, 26 lutego 2018

[PL] SQL Server 2012 SP4 - jak wykryć fakt zmiany danych w tabeli i zapisać informacje na ten temat w bazie danych?

Dzisiaj, korzystając z SQL Servera, spróbujemy zarejestrować w bazie danych informacje o tym, że dane w wybranej kolumnie w określonej tabeli zostały zmodyfikowane. 
Zacznijmy od utworzenia tabeli testowej korzystając z poniższego kodu:

USE BazaTestowa
GO

CREATE TABLE dbo.Osoby (
Id BIGINT IDENTITY(1,1)
               NOT NULL
               PRIMARY KEY,
Imie nvarchar(200) NOT NULL,
Nazwisko nvarchar(200) NOT NULL,
DataUrodzenia date NOT NULL,
Plec char(1) NOT NULL,
Miasto varchar(100) NOT NULL,
Kraj varchar(20) NOT NULL,
Przeprowadzka bit,
PrzeprowadzkaData date
);

Jak widzimy powyżej, nasza testowa tabela:
  • została utworzona w schemacie dbo
  • nosi nazwę Osoby
  • została stworzona w celu ewidencjonowania danych o osobach, w tym: imienia (kolumna Imie), nazwiska (kolumna Nazwisko), daty urodzenia (kolumna DataUrodzenia), płci (kolumna Plec), miasta (kolumna Miasto), kraju (kolumna Kraj)
  • w kolumnie Plec pozwala na zapisywanie danych na temat płci zgodnie ze standardem PN-ISO 5218:
    • 0 – płeć nieokreślona
    • 1 – mężczyzna
    • 2 - kobieta
    • 9 – nieznana
  • zawiera kolumny Przeprowadza i PrzeprowadzkaData w których zapisywać będziemy informacje o fakcie zmiany adresu przez osobę
  • zawiera kolumnę ID, która jest kluczem podstawowym i wartości - na potrzeby tej kolumny - są generowanie automatycznie dla każdego wiersza, zaczynając od 1 i wzrastając co 1
Załadujmy dane do naszej testowej tabeli:

INSERT INTO dbo.Osoby (Imie, Nazwisko, DataUrodzenia, Plec, Miasto, Kraj)
VALUES (N'Jan',N'Kowalski', '1990-01-01', '1', 'Warszawa', 'Polska');
INSERT INTO dbo.Osoby (Imie, Nazwisko, DataUrodzenia, Plec, Miasto, Kraj)
VALUES (N'Anna',N'Kowalska', '1980-01-01', '1', 'Szczecin', 'Polska');
INSERT INTO dbo.Osoby (Imie, Nazwisko, DataUrodzenia, Plec, Miasto, Kraj)
VALUES (N'Tadeusz',N'Wiśniewski', '1984-01-01', '1', 'Kraków', 'Polska');

Sprawdźmy, że tabela dbo.Osoby zawiera dodane przed chwilą dane – powinny znajdować się w niej trzy rekordy. Zwróćmy uwagę na kolumny Przeprowadzka i PrzeprowadzkaData – nie mają one żadnej wartości.

SELECT * FROM dbo.Osoby;


Kolejnym krokiem jest utworzenie triggera, czyli wyzwalacza, który:
  • będzie włączał się po każdej operacji aktualizacji danych w tabeli dbo.Osoby
  • będzie sprawdzać czy zmianie uległy dane w kolumnie Miasto lub Kraj
  • jeżeli dane w kolumnie Miasto lub Kraj zostają zmienione, to kolumna Przeprowadzka zostanie uzupełniona wartością 1, a PrzeprowadzkaData – bieżącą datą

CREATE TRIGGER dbo.OsobyAfterUpdate01
ON dbo.Osoby
AFTER UPDATE
AS
IF ( UPDATE (MIASTO) OR UPDATE (KRAJ) ) 
BEGIN
SET NOCOUNT ON;
UPDATE dbo.Osoby SET
Przeprowadzka = 1,
PrzeprowadzkaData = GETDATE()
from deleted d, dbo.Osoby o
where d.Id = o.Id
END
GO

Czas na końcowe testy – sprawdźmy działanie triggera. Aby to zrobić, zaktualizujmy dane w kolumnie Miasto dla wiersza z identyfikatorem 2, a następnie wyświetlmy aktualną zawartość tabeli dbo.Osoby.

UPDATE dbo.Osoby
SET Miasto = 'Gdańsk'
WHERE Id = 2;

SELECT * FROM dbo.Osoby;

Wynik powinien być następujący:


Czyli pożądana zmiana została wprowadzona (wartość kolumny Miasto została zmieniona), a ponadto trigger zadziałał prawidłowo – dla rekordu o identyfikatorze 2 została zaktualizowana zawartość kolumny Przeprowadzka i PrzeprowadzkaData.

Żeby mieć pewność, że wszystko działa prawidłowo, zróbmy jeszcze jeden test, który upewni nas, że trigger nie zadziała w przypadku aktualizacji danych w innej kolumnie niż Miasto lub Kraj, np. Plec. Zaktualizujmy zatem dla rekordu o identyfikatorze 3 wartość kolumny Plec z 1 (mężczyzna) na 9 (nieznana) i sprawdźmy aktualną zawartość tabeli dbo.Osoby.

UPDATE dbo.Osoby
SET Plec = '9'
WHERE Id = 3;

SELECT * FROM dbo.Osoby;


W tym przypadku również widzimy, że wszystko zadziałało prawidłowo, ponieważ dla rekordu o identyfikatorze 3 kolumny Przeprowadzka i PrzeprowadzkaData pozostały bez wartości, czyli trigger nie zaktualizował niepotrzebnie kolumn Przeprowadzka i PrzeprowadzkaData - stało się tak za sprawą warunku IF ( UPDATE (MIASTO) OR UPDATE (KRAJ) )  zawartego w triggerze, gdyż funkcja UPDATE służy do wykrywania zmian na określonej kolumnie. 

poniedziałek, 19 lutego 2018

[PL] SQL Server 2014 SP2 - funkcja @@TRANCOUNT

Wbudowana w SQL Server funkcja @@TRANCOUNT pozwala na wyświetlenie liczby otwartych transakcji w ramach obecnego połączenia z bazą danych.  Aby rozpocząć transakcję korzystamy z polecenia BEGIN TRANSACTION, do zatwierdzenia rozpoczętej transakcji służy polecenie COMMIT TRANSACTION, z kolei anulować rozpoczętą transakcję należy skorzystać z polecenia ROLLBACK TRANSACTION

Wykonanie polecenia
SELECT @@TRANCOUNT AS ilosc_transakcji 

powinno zwrócić wartość 0, gdyż w momencie jego uruchomienia nie ma żadnych otwartych transakcji.





Aby zademonstrować działanie @@TRANCOUNT w praktyce spróbujmy więc: 1) sprawdzić ilość rozpoczętych transakcji; 2) rozpocząć transakcję; 3) sprawdzić ilość rozpoczętych transakcji; 4) anulować rozpoczętą transakcję; 5) sprawdzić ilość rozpoczętych transakcji.  W tym celu skorzystajmy z polecenia:
-- krok 1
SELECT @@TRANCOUNT AS ilosc_transakcji_krok1
-- krok 2
BEGIN TRANSACTION
-- krok 3
SELECT @@TRANCOUNT AS ilosc_transakcji_krok3
-- krok 4
ROLLBACK TRANSACTION
-- krok 5
SELECT @@TRANCOUNT AS ilosc_transakcji_krok5
Wynik będzie następujący:



Powyższy przykład obrazuje, że przed rozpoczęciem transakcji, ilość rozpoczętych transakcji wynosiła 0, po rozpoczęciu jednej transakcji ilość wynosiła 1, a po jej zakończeniu ilość rozpoczętych transakcji wynosiła ponownie 0. 

poniedziałek, 12 lutego 2018

[PL] Jak centralnie zarządzać wieloma serwerami MS SQL Server 2014?

Czasami w życiu każdego administratora baz danych zdarza się sytuacja, kiedy pojawia się zadanie typu "sprawdź czy poprawka XYZ jest zainstalowana na każdym serwerze". Są wówczas dwie możliwości zrealizowania takiego zadania. Pierwsza z nich to połączenie się do każdej instancji SQL Server i wykonanie określonych czynności. Druga metoda to skorzystanie z funkcjonalności zwanej Central Managament Server, która pozwala - na przykład - na wykonanie konkretnego zapytania wobec wielu serwerów (instancji) jednocześnie, w tym samym czasie. Poniżej prezentuję przykład zastosowania drugiej z wymienionych opcji. Jest ona dostępna w systemie Microsoft SQL Server od wersji 2008.

W SQL Server Managament Studio:
1. Wybieramy ViewRegistered Servers


2. W panelu Registered Servers klikamy prawym przyciskiem myszy na Central Managament Servers i wybieramy Register Central Managament Server...


3. W oknie New Server Registration na zakładce General wprowadzamy dane na potrzeby połączenia z instancją SQL Server. Podajemy tutaj dane serwera, na którym aktualnie pracujemy. Na zakładce Connection Proporties warto zaznaczyć opcję  Use custom color i wybrać unikalny kolor charakteryzujący połączenie z tym konkretnym serwerem. Na karcie  General klikamy na przycisk Test, aby przeprowadzić test połączenia i jeżeli wynik testu jest pomyślny - naciskamy Save




4. Klikamy prawym przyciskiem myszy na instancję SQL Server, którą dodaliśmy przed chwilą i wybieramy New Server Group


5. W oknie New Server Group Proporties w polu Group Name wprowadzamy nazwę grupy serwerów, np. "serwery z bazą danych aplikacji XYZ" i wybieramy OK


6. Klikamy prawym przyciskiem myszy na utworzoną przed chwilą grupę i wybieramy New Server Registration


7. W oknie New Server Registration na zakładce General wprowadzamy dane na potrzeby połączenia z instancją SQL Server. Podajemy tutaj dane kolejnego serwera. Na zakładce Connection Proporties warto zaznaczyć opcję  Use custom color i wybrać unikalny kolor charakteryzujący połączenie z tym konkretnym serwerem. Na karcie  General klikamy na przycisk Test, aby przeprowadzić test połączenia i jeżeli wynik testu jest pomyślny - naciskamy Save




8. Powtarzamy kroki 6 i 7 aby zarejestrować kolejne serwery w grupie.  

W moim przypadku SQL01 to serwer zarządzający na którym pracuję, a AD01\KSIEGOWA i DB01\KADRY to serwery, którymi będę zdalnie zarządzać na poziomie grupy.



9. Aby wykonać zapytanie na kilku serwerach jednocześnie, klikamy prawym przyciskiem myszy na grupę serwerów i wybieramy New Query


10. W oknie tworzenia nowego zapytania, w standardowy sposób wprowadzamy jego treść i klikamy na Execute. Po chwili naszym oczom powinien ukazać się wynik zapytania z dokładnością do każdego serwera w grupie serwerów, na której wykonujemy zapytanie. Poniżej zdjęcie z wynikiem przykładowego zapytania SELECT @@VERSION oraz z działania polecenia tworzącego nową bazę danych. 



poniedziałek, 5 lutego 2018

[PL] SQL Server 2014 SP2 - widok dm_db_persisted_sku_features

W SQL Serverze istnieje wbudowany widok sys.dm_db_persisted_sku_features, wynikiem działania którego jest lista wykorzystywanych przez nas funkcji charakterystycznych dla posiadanej edycji SQL Server. Na przykład jeżeli wykorzystujemy partycjonowanie w SQL Server Enterprise Edition, to wówczas zapytanie: 
SELECT * FROM sys.dm_db_persisted_sku_features
zwróci informację na ten temat i oznaczać to będzie, że bazy danych, na której pracujemy, nie przeniesiemy z powodzeniem do innej edycji SQL Servera, która nie posiada obsługi partycjonowania (np. z Enterprise do Express).  Listę funkcji, o których może nas poinformować widok sys.dm_db_persisted_sku_features znajdziemy na stronie Microsoft Docs - są to m.in.: indeksy ColumnStore i partycjonowanie. 

Warto też zerknąć do artykułu Editions and supported features of SQL Server 2017, który opisuje funkcje i ograniczenia poszczególnych edycji SQL Servera (na przykładzie wersji 2017).