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 \ Databases \ test \ Tables \ dbo.test table'に違反しています。このトランザクションはロールバックされます。ポリシー条件: '@Name NOT LIKE'%[-。]% 'AND @Name NOT LIKE'%[^ A-Za-z0-9 [_]]% ''ポリシーの説明: ''追加のヘルプ: '': ''ステートメント: 'CREATE TABLE [テストテーブル](Id INT NULL)'。メッセージ3609、レベル16、状態1、プロシージャsp_syspolicy_dispatch_event、行65 [バッチ開始行48]トランザクションはトリガーで終了しました。バッチは中止されました。

次のコードを実行しても、エラーは発生しません。

CREATE TABLE [testtable]
(Id INT NULL)

ただし、CREATE TABLESQL Server 2016でポリシーを有効にしてステートメントを実行すると、次のエラーが発生します。

ポリシー 'テーブル名'は 'SQLSERVER:\ SQL \ LSRSQL07 \ SQL2016 \ Databases \ test \ Tables \ dbo.testtable'に違反しています。このトランザクションはロールバックされます。ポリシー条件: '@Name NOT LIKE'%% ''ポリシーの説明: ''追加のヘルプ: '': ''ステートメント: 'CREATE TABLE [testtable](Id INT NULL)'。メッセージ515、レベル16、状態2、プロシージャsp_syspolicy_execute_policy、行69 [バッチ開始行44]列 'target_query_expression'、テーブル 'msdb.dbo.syspolicy_policy_execution_history_details_internal'に値NULLを挿入できません。列はnullを許可しません。INSERTは失敗します。ステートメントは終了されました。

SQL Server 2016では、条件を通過するかどうかに関係なく、テーブルを作成できません。

これはSQL Server 2016、SP1、CU3です。

これに関するアイデアはありますか?

編集:評価モードを「変更時:防止」にする必要があります

回答:


6

SQL Server 2016 SP1 CU2インスタンスでスクリプトをテストしました。評価モードが「変更時:防止」に設定されている場合、ポリシーは機能します。(特定のファセットを使用するポリシーを評価できないバグがあります)。

一方、テーブル名にのみポリシーを使用する場合は、同じ構成で、「MultipartName」の代わりに「Table Option」ファセットを試すこともできます(@NAME NOT LIKE '% %')。


評価モードを「オンデマンド」に設定すると機能しますが、公平を期すために、以前は試していませんでした。私はこれを変更したい:人々がテーブルを作成することを防ぎ、悪名のあるテーブルを参照するストアドプロシージャを防止する。
John

私にとっては、評価モードを「オンデマンド」に設定してポリシーを手動で評価することはできません。ただし、評価が「On Change:Prevent」に設定されていて、テーブルを作成しようとすると、正常に機能します。問題をMicrosoft Connectに投稿して、バグかどうかを確認することができます。
Dragos

ありがとう、@ Dragos。条件を通過する必要があるテーブルでさえ、どのテーブルでも発生していますか?
ジョン

名前に空白がないテーブルは正常に作成され、空白があるテーブルはポリシー違反エラーで失敗します。
Dragos

ストアドプロシージャとビューファセットで同じ問題が発生しています。SQL 2016 SP1 CU3(最新)を使用しています。ジョンが述べたように、これはバグのように見えますが、誰かが回避策を理解できるかどうか疑問に思いましたか?
DBAuser 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.