ปัญหาเกี่ยวกับแบบแผนการตั้งชื่อตารางและการจัดการนโยบายใน 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 ตาราง' ธุรกรรมนี้จะถูกย้อนกลับ เงื่อนไขนโยบาย: '@Name ไม่ชอบ'% [-.]% 'และ @Name ไม่ชอบ'% [^ A-Za-z0-9 [_]]% '' คำอธิบายนโยบาย: '' ความช่วยเหลือเพิ่มเติม: '': '' คำชี้แจง: 'สร้างตาราง [ตารางทดสอบ] (Id INT NULL)' ข่าวสารเกี่ยวกับ 3609, ระดับ 16, สถานะ 1, กระบวนงาน sp_syspolicy_dispatch_event, บรรทัดที่ 65 [Batch Start Line 48] ธุรกรรมสิ้นสุดลงในทริกเกอร์ ชุดงานถูกยกเลิก

และถ้าฉันเรียกใช้รหัสต่อไปนี้ฉันจะไม่มีข้อผิดพลาด:

CREATE TABLE [testtable]
(Id INT NULL)

อย่างไรก็ตามถ้าฉันเรียกใช้CREATE TABLEคำสั่งใด ๆด้วยการเปิดใช้งานนโยบายบน SQL Server 2016 ฉันได้รับข้อผิดพลาดต่อไปนี้:

นโยบาย 'ชื่อตาราง' ถูกละเมิดโดย 'SQLSERVER: \ SQL \ LSRSQL07 \ SQL2016 \ Databases \ test \ Tables \ dbo.testtable' ธุรกรรมนี้จะถูกย้อนกลับ เงื่อนไขของนโยบาย: '@Name ไม่ชอบ'%% '' คำอธิบายนโยบาย: '' ความช่วยเหลือเพิ่มเติม: '': '' ข้อความ: 'สร้างตาราง [testtable] (Id INT NULL)' ข่าวสารเกี่ยวกับ 515, ระดับ 16, สถานะ 2, โพรซีเดอร์ sp_syspolicy_execute_policy, บรรทัดที่ 69 [Batch Start Line 44] ไม่สามารถแทรกค่า NULL ลงในคอลัมน์ คอลัมน์ไม่อนุญาตให้มีค่า Null INSERT ล้มเหลว คำสั่งถูกยกเลิก

ใน SQL Server 2016 ฉันไม่สามารถสร้างตารางใด ๆไม่ว่าจะผ่านเงื่อนไขหรือไม่

นี่คือ SQL Server 2016, SP1, CU3

ความคิดใด ๆ เกี่ยวกับเรื่องนี้?

แก้ไข: ฉันต้องการให้โหมดการประเมินเป็น "On change: ป้องกัน"

คำตอบ:


6

ทดสอบสคริปต์บนอินสแตนซ์ CU2 SQL Server 2016 SP1 และนโยบายใช้งานได้หากตั้งโหมดการประเมินเป็น "On Change: Prevent" (มีข้อบกพร่องที่ไม่อนุญาตให้คุณประเมินนโยบายที่ใช้ facets เฉพาะ)

ในขณะเดียวกันหากคุณใช้นโยบายสำหรับชื่อตารางเท่านั้นคุณสามารถลองใช้ "ตัวเลือกตาราง" ด้านแทน "MultipartName" ด้วยการกำหนดค่าเดียวกัน ( @NAME NOT LIKE '% %')


หากฉันตั้งค่าโหมดการประเมินผลเป็น "ตามคำขอ" มันใช้งานได้ แต่จะยุติธรรมฉันไม่เคยลองใช้โหมดนี้มาก่อน ฉันต้องการที่จะมีการเปลี่ยนแปลงนี้: ป้องกันเพื่อป้องกันไม่ให้คนสร้างตารางแล้วเก็บ procs อ้างอิงตารางที่มีชื่อไม่ดี
John

สำหรับฉันมันไม่ทำงานเพื่อตั้งค่าโหมดการประเมินผลเป็น "ตามความต้องการ" และประเมินนโยบายด้วยตนเอง แต่จะใช้งานได้ดีหากการประเมินผลถูกตั้งค่าเป็น "เมื่อเปลี่ยน: ป้องกัน" และพยายามสร้างตาราง คุณสามารถลองโพสต์ปัญหาบน Microsoft Connect เพื่อดูว่ามันเป็นบั๊กหรือไม่
Dragos

ขอบคุณ @Dragos มันเกิดขึ้นบนโต๊ะใด ๆ แม้กระทั่งสิ่งที่ควรผ่านเงื่อนไข?
John

ตารางที่ไม่มีช่องว่างสีขาวในชื่อถูกสร้างขึ้นสำเร็จและรายการที่มีช่องว่างสีขาวล้มเหลวด้วยข้อผิดพลาดการละเมิดนโยบาย
Dragos

เรากำลังประสบปัญหาเดียวกันกับขั้นตอนการจัดเก็บและมุมมอง เราอยู่ใน SQL 2016 SP1 CU3 (ล่าสุด) เช่นเดียวกับจอห์นกล่าวว่าสิ่งนี้ดูเหมือนจะเป็นข้อผิดพลาด แต่ก็สงสัยว่าถ้าใครสามารถหาวิธีแก้ปัญหาได้?
DBAuser
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.