Проблема з умовами імен таблиць та управління політикою в SQL Server 2016


10

У SQL Server 2012 у мене була встановлена ​​політика забороняти пробіли в імені таблиці. Однак, коли я використовую ту саму політику в SQL Server 2016, я отримую помилку.

Ось код умови:

DECLARE @condition_id INT
EXEC msdb.dbo.sp_syspolicy_add_condition @name=N'No Spaces', @description=N'No spaces in table names.', @facet=N'IMultipartNameFacet', @expression=N'<Operator>
  <TypeClass>Bool</TypeClass>
  <OpType>NOT_LIKE</OpType>
  <Count>2</Count>
  <Attribute>
    <TypeClass>String</TypeClass>
    <Name>Name</Name>
  </Attribute>
  <Constant>
    <TypeClass>String</TypeClass>
    <ObjType>System.String</ObjType>
    <Value>% %</Value>
  </Constant>
</Operator>', @is_name_condition=4, @obj_name=N'% %', @condition_id=@condition_id OUTPUT
SELECT @condition_id

Ось код політики:

DECLARE @object_set_id INT
EXEC msdb.dbo.sp_syspolicy_add_object_set @object_set_name=N'Table Names_ObjectSet', @facet=N'IMultipartNameFacet', @object_set_id=@object_set_id OUTPUT
SELECT @object_set_id

DECLARE @target_set_id INT
EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Table Names_ObjectSet', @type_skeleton=N'Server/Database/Sequence', @type=N'SEQUENCE', @enabled=False, @target_set_id=@target_set_id OUTPUT
SELECT @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0
EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database/Sequence', @level_name=N'Sequence', @condition_name=N'', @target_set_level_id=0

EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Table Names_ObjectSet', @type_skeleton=N'Server/Database/StoredProcedure', @type=N'PROCEDURE', @enabled=False, @target_set_id=@target_set_id OUTPUT
SELECT @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0
EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database/StoredProcedure', @level_name=N'StoredProcedure', @condition_name=N'', @target_set_level_id=0

EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Table Names_ObjectSet', @type_skeleton=N'Server/Database/Synonym', @type=N'SYNONYM', @enabled=False, @target_set_id=@target_set_id OUTPUT
SELECT @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0
EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database/Synonym', @level_name=N'Synonym', @condition_name=N'', @target_set_level_id=0

EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Table Names_ObjectSet', @type_skeleton=N'Server/Database/Table', @type=N'TABLE', @enabled=True, @target_set_id=@target_set_id OUTPUT
SELECT @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0
EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database/Table', @level_name=N'Table', @condition_name=N'', @target_set_level_id=0

EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Table Names_ObjectSet', @type_skeleton=N'Server/Database/UserDefinedFunction', @type=N'FUNCTION', @enabled=False, @target_set_id=@target_set_id OUTPUT
SELECT @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0
EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database/UserDefinedFunction', @level_name=N'UserDefinedFunction', @condition_name=N'', @target_set_level_id=0

EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Table Names_ObjectSet', @type_skeleton=N'Server/Database/UserDefinedType', @type=N'TYPE', @enabled=False, @target_set_id=@target_set_id OUTPUT
SELECT @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0
EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database/UserDefinedType', @level_name=N'UserDefinedType', @condition_name=N'', @target_set_level_id=0

EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Table Names_ObjectSet', @type_skeleton=N'Server/Database/View', @type=N'VIEW', @enabled=False, @target_set_id=@target_set_id OUTPUT
SELECT @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0
EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database/View', @level_name=N'View', @condition_name=N'', @target_set_level_id=0

EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Table Names_ObjectSet', @type_skeleton=N'Server/Database/XmlSchemaCollection', @type=N'XMLSCHEMACOLLECTION', @enabled=False, @target_set_id=@target_set_id OUTPUT
SELECT @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0
EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database/XmlSchemaCollection', @level_name=N'XmlSchemaCollection', @condition_name=N'', @target_set_level_id=0


GO

DECLARE @policy_id INT
EXEC msdb.dbo.sp_syspolicy_add_policy @name=N'Table Names', @condition_name=N'No Spaces', @policy_category=N'', @description=N'', @help_text=N'', @help_link=N'', @schedule_uid=N'00000000-0000-0000-0000-000000000000', @execution_mode=1, @is_enabled=True, @policy_id=@policy_id OUTPUT, @root_condition_name=N'', @object_set=N'Table Names_ObjectSet'
SELECT @policy_id


GO

У SQL Server 2012 та 2014 роках це дає очікувані результати:

CREATE TABLE [test table]
(Id INT NULL)

Політика "Імена таблиць" порушена "SQLSERVER: \ SQL \ LSRSQL07 \ SQL2012 \ Бази даних \ тест \ Таблиці \ dbo.test таблиця". Ця транзакція буде повернута назад. Умова політики: '@Name NOT LIKE'% [-.]% 'AND @Name NOT LIKE'% [^ A-Za-z0-9 [_]]% '' Опис політики: '' Додаткова допомога: '': '' Заява: 'CREATE TABLE [тестова таблиця] (Id INT NULL)'. Msg 3609, Рівень 16, Стан 1, Процедура sp_syspolicy_dispatch_event, Рядок 65 [Початкова лінія рядка 48] Угода закінчилася тригером. Партія була перервана.

І якщо я запускаю наступний код, я не отримую помилок:

CREATE TABLE [testtable]
(Id INT NULL)

Однак якщо я запускаю будь-який CREATE TABLEоператор із ввімкненою політикою на SQL Server 2016, я отримую таку помилку:

Політика "Імена таблиць" порушена "SQLSERVER: \ SQL \ LSRSQL07 \ SQL2016 \ Бази даних \ тест \ Таблиці \ dbo.testtable". Ця транзакція буде повернута назад. Умова політики: '@Name NOT LIKE'%% '' Опис політики: '' Додаткова допомога: '': '' Заява: 'CREATE TABLE [testtable] (Id INT NULL)'. Msg 515, рівень 16, стан 2, процедура sp_syspolicy_execute_policy, рядок 69 [Початкова лінія рядка 44] Неможливо вставити значення NULL у стовпчик 'target_query_expression', таблиця 'msdb.dbo.syspolicy_policy_execution_history_details_internal'; стовпець не дозволяє нулів. INSERT не вдається. Заява скасована.

У SQL Server 2016 я не можу створити будь-яку таблицю , переходить вона в умову чи ні.

Це SQL Server 2016, SP1, CU3.

Будь-які ідеї з цього приводу?

Редагувати: мені потрібен режим оцінювання, щоб він був "У зміні: запобігти"

Відповіді:


6

Перевірено сценарії на екземплярі SU Server 2016 SP1 CU2, і політика працює, якщо для режиму оцінки встановлено значення "Увімкнути зміни: запобігти". (є помилка , яка не дозволяє оцінювати політику, яка використовує конкретні аспекти).

Тим часом, якщо ви використовуєте політику лише для імен таблиць, ви можете також спробувати фасет "Параметр таблиці" замість "MultipartName", з тією ж конфігурацією ( @NAME NOT LIKE '% %').


Якщо я встановив для режиму оцінювання значення "На вимогу", це спрацює, але якщо чесно, я раніше цього не пробував. Я б хотів, щоб це було на зміні: не дозволяйте людям створювати таблиці, а потім зберігати документи, що посилаються на погано названі таблиці.
Джон

Для мене не працює, щоб встановити режим оцінки на "За запитом" та оцінити політику вручну. Але це добре працює, якщо для оцінки встановлено значення "Увімкнути зміни: запобігти" і спробувати створити таблиці. Ви можете спробувати опублікувати проблему на Microsoft Connect, щоб з’ясувати, помилка чи ні.
Драгос

Дякую, @Dragos. Чи трапляється це на будь-якому столі, навіть на тих, які мають передати умову?
Джон

Таблиці, у яких в назві немає білих пробілів, успішно створюються, а ті, у яких пробіли білі, провалюються з помилкою порушення політики.
Драгос

У нас виникає та сама проблема із збереженою процедурою та переглядом граней. Ми перебуваємо на SQL 2016 SP1 CU3 (Останні). Як заявив Джон, це здається помилкою, але цікаво, чи хтось зможе розібратися у вирішенні проблеми?
DBAuser
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.