Sự cố với Quy ước đặt tên bảng và Quản lý chính sách trong SQL Server 2016


10

Trong SQL Server 2012, tôi đã có một chính sách được đặt thành không cho phép khoảng trắng trong tên bảng. Tuy nhiên, khi tôi sử dụng chính sách tương tự trong SQL Server 2016, tôi gặp lỗi.

Đây là mã cho điều kiện:

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

Đây là mã cho chính sách:

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

Trong SQL Server 2012 và 2014, điều này mang lại kết quả như mong đợi:

CREATE TABLE [test table]
(Id INT NULL)

Chính sách 'Tên bảng' đã bị vi phạm bởi 'SQLSERVER: \ SQL \ LSRSQL07 \ SQL2012 \ Cơ sở dữ liệu \ test \ Bàn \ dbo.test bảng'. Giao dịch này sẽ được khôi phục. Điều kiện chính sách: '@Name KHÔNG THÍCH'% ​​[-.]% 'VÀ @Name KHÔNG THÍCH'% ​​[^ A-Za-z0-9 [_]]% '' Mô tả chính sách: '' Trợ giúp bổ sung: '': '' Tuyên bố: 'TẠO BẢNG [bảng thử nghiệm] (Id INT NULL)'. Msg 3609, Cấp 16, Trạng thái 1, Quy trình sp_syspolicy_dispatch_event, Dòng 65 [Batch Start Line 48] Giao dịch kết thúc trong trình kích hoạt. Các lô đã bị hủy bỏ.

Và nếu tôi chạy đoạn mã sau, tôi không gặp lỗi:

CREATE TABLE [testtable]
(Id INT NULL)

Tuy nhiên, nếu tôi chạy bất kỳ CREATE TABLEcâu lệnh nào , với chính sách được bật, trên SQL Server 2016, tôi sẽ gặp lỗi sau:

Chính sách 'Tên bảng' đã bị vi phạm bởi 'SQLSERVER: \ SQL \ LSRSQL07 \ SQL2016 \ Cơ sở dữ liệu \ test \ Bàn \ dbo.testtable'. Giao dịch này sẽ được khôi phục. Điều kiện chính sách: '@Name KHÔNG THÍCH' %% '' Mô tả chính sách: '' Trợ giúp bổ sung: '': '' Tuyên bố: 'TẠO BẢNG [testtable] (Id INT NULL)'. Msg 515, Cấp 16, Trạng thái 2, Quy trình sp_syspolicy_execute_policy, Dòng 69 [Batch Start Line 44] Không thể chèn giá trị NULL vào cột 'target_query_expression', bảng 'msdb.dbo.syspolicy_policy_execut_history cột không cho phép null. XÁC NHẬN thất bại. Các tuyên bố này đã bị chấm dứt.

Trong SQL Server 2016, tôi không thể tạo bất kỳ bảng nào , cho dù nó có vượt qua điều kiện hay không.

Đây là SQL Server 2016, SP1, CU3.

Bất cứ ý tưởng về điều này?

Chỉnh sửa: Tôi cần chế độ đánh giá là "Thay đổi: ngăn chặn"

Câu trả lời:


6

Đã kiểm tra các tập lệnh trên phiên bản SQL Server 2016 SP1 CU2 và chính sách hoạt động nếu chế độ Đánh giá được đặt thành "Bật thay đổi: Ngăn chặn". (có một lỗi không cho phép bạn đánh giá các chính sách sử dụng các khía cạnh cụ thể).

Trong khi đó, nếu bạn chỉ sử dụng chính sách cho tên bảng, bạn cũng có thể thử khía cạnh "Tùy chọn bảng" thay vì "MultipartName", với cùng cấu hình ( @NAME NOT LIKE '% %').


Nếu tôi đặt chế độ đánh giá thành "Theo yêu cầu", nó sẽ hoạt động, nhưng để công bằng, tôi đã không thử điều đó trước đây. Tôi muốn có thay đổi này: ngăn không cho mọi người tạo bảng và sau đó lưu trữ procs tham chiếu các bảng có tên xấu.
Giăng

Đối với tôi, nó không hoạt động để đặt chế độ đánh giá thành "Theo yêu cầu" và đánh giá chính sách theo cách thủ công. Nhưng nó hoạt động tốt nếu đánh giá được đặt thành "Bật thay đổi: Ngăn chặn" và cố gắng tạo các bảng. Bạn có thể thử đăng sự cố lên Microsoft Connect để tìm hiểu xem đó có phải là lỗi hay không.
Dragos

Cảm ơn, @Dragos. Có xảy ra trên bất kỳ bảng, ngay cả những người nên vượt qua điều kiện?
John

Các bảng không có khoảng trắng trong tên được tạo thành công và các bảng có khoảng trắng không thành công với lỗi vi phạm chính sách.
Dragos

Chúng tôi đang có cùng một vấn đề với thủ tục được lưu trữ và xem các khía cạnh. Chúng tôi đang trên SQL 2016 SP1 CU3 (Mới nhất). Giống như John đã nêu, đây có vẻ như là một lỗi nhưng tự hỏi liệu có ai có thể tìm ra cách giải quyết không?
DBAuser
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.