[PL] Policy-Based Management – warunek nie dla filtrów
Siedząc w firmie nad materiałami do szkolenia z SQL Server 2008 dla moich współpracowników, natknąłem się na pewien problem, którego nie udało mi się przeskoczyć.
Chciałem użyć mechanizmów Policy-Based Management do sprawdzania pewnego warunku na bazach danych, ale tylko dla baz danych spełniających określony przeze mnie warunek. Tym warunkiem miało być istnienie w bazie danych obiektu o wskazanej nazwie.
Zacząłem od stworzenia warunku do sprawdzania wybranej przeze mnie właściwości. To było proste i każdy chyba sobie z tym poradzi bez problemu. W Management Studio w oknie Object Explorer należy kliknąć prawym przyciskiem myszy na Management – Policy Management – Conditions i wybrać z menu kontekstowego New Condition…
Warunek założyłem taki:
Łatwizna :-)
Teraz zakładam drugi warunek, który w zamierzeniu ma mi posłużyć do filtrowania baz danych.
No, ten warunek już jest nieco bardziej "fikuśny", bo użyłem w nim wyrażenia z użyciem dostępnego mini-języka skryptowego używanego przez Policy-Based Management :-) Ale generalnie jest to sprawdzenie, czy w bazie danych istnieje obiekt o nazwie ufn_GetVersion.
Po wykonaniu tych kroków przyszedł czas na założenie polisy. Klikam więc prawym przyciskiem myszy na Management – Policy Management – Policies i wybieram New Policy…
I kiszka – nie widzę na liście warunków, których mógłbym użyć do filtrowania baz danych, mojego warunku na istnienie obiektu… Pierwsza myśl - "nie da się". Druga myśl - "a może to wina GUI?". Zeskryptowałem więc powyższą polisę (używając przycisku Script widocznego na powyższym rysunku. Wyleciało mi przed oczy coś takiego:
1: DECLARE @object_set_id INT
2: EXEC msdb.dbo.sp_syspolicy_add_object_set @object_set_name = N'Database Owner Must Be sa AND _ObjectSet',
3: @facet = N'Database',
4: @object_set_id = @object_set_id OUTPUT
5: SELECT
6: @object_set_id
7:
8: DECLARE @target_set_id INT
9: EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name = N'Database Owner Must Be sa AND _ObjectSet',
10: @type_skeleton = N'Server/Database',
11: @type = N'DATABASE',
12: @enabled = True,
13: @target_set_id = @target_set_id OUTPUT
14: SELECT
15: @target_set_id
16:
17: EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id = @target_set_id,
18: @type_skeleton = N'Server/Database',
19: @level_name = N'Database',
20: @condition_name = N'',
21: @target_set_level_id = 0
22: GO
23:
24: DECLARE @policy_id INT
25: EXEC msdb.dbo.sp_syspolicy_add_policy @name = N'Database Owner Must Be sa WHERE Object Exists',
26: @condition_name = N'Database Owner Must Be sa',
27: @execution_mode = 0,
28: @policy_id = @policy_id OUTPUT,
29: @object_set = N'Database Owner Must Be sa AND _ObjectSet'
30: SELECT
31: @policy_id
32: GO
Moją uwagę przykuła linia 20. Ha! A może w kodzie się to da zrobić! Zmodyfikowałem więc linię 20, by wyszło:
20: @condition_name = N'Database Has Object Named ufn_GetVersion',
a następnie uruchomiłem całość i o dziwo… poszło!
Zadowolony wypróbowałem nowo utworzoną polisę klikając prawym przyciskiem na mojej polisie (najpierw trzeba było odświeżyć widok w Object Explorerze, bo oczywiście polisa się nie pojawiła) i wybierając Evaluate. Niestety, odpowiedź polisy nie była taka, jakiej się spodziewałem…
Próbowałem namierzyć polecenie T-SQL, na którym wywraca się polisa, ale poległem. Przezornie zajrzałem więc do okienka właściwości warunku, którego "nielegalnie" użyłem do filtrowania baz danych i zobaczyłem takie coś:
Komunikat w górnej części okna rozwiał moje wątpliwości. Się nie da się :-)
I teraz ciekawostka – Marek Powichrowski, który był tak miły i przetestował problem, zauważył, że warunki budowane na wyrażeniach, daje się zastosować do filtrowania serwerów! Co tu jest grane? Mała niekonsekwencja, rzekłbym.
Jeśli ktoś potrafi znaleźć workaround dla pokazanego problemu, niech da znać. A może w dokumentacji komuś uda się znaleźć zdanie, które jednoznacznie powie, że warunki oparte na wyrażeniach nie mogą być używane do filtrowania?
Samo Policy-Based Management bardzo mi się podoba. Ale chciałbym mieć pewność, że daje się budować swobodnie warunki i używać ich wedle mojego uznania, a nie wedle uznania SQL Servera :-)
Na koniec małe repozytorium materiałów autorstwa Damiana Widery na temat Policy-Based Management:
SQL Server 2008 – Declarative Management Framework krok po kroku
C2C'08 - Damian Widera - Microsoft SQL Server 2008 Policy-Based Management na zewnątrz i od środka