Server 2016'da Tablo Adlandırma Kuralları ve İlke Yönetimi ile ilgili Sorun


10

SQL Server 2012'de, tablo adındaki boşluklara izin vermeyecek şekilde ayarlanmış bir ilkem vardı. Ancak, aynı ilkeyi SQL Server 2016'da kullandığımda bir hata alıyorum.

Durumun kodu:

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

Politikanın kodu şöyledir:

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 ve 2014'te bu beklenen sonuçları verir:

CREATE TABLE [test table]
(Id INT NULL)

'Tablo Adları' ilkesi 'SQLSERVER: \ SQL \ LSRSQL07 \ SQL2012 \ Databases \ test \ Tables \ dbo.test table' tarafından ihlal edildi. Bu işlem geri alınacak. Politika koşulu: '@Ad GİBİ DEĞİL'% [-.]% 'VE @Name GİBİ DEĞİL'% [^ A-Za-z0-9 [_]]% '' Politika açıklaması: '' Ek yardım: '': '' Statement: 'CREATE TABLE [test tablosu] (Id INT NULL)'. Msg 3609, Seviye 16, Durum 1, Prosedür sp_syspolicy_dispatch_event, Satır 65 [Toplu Başlangıç ​​Satırı 48] İşlem tetikleyicide sona erdi. Toplu iş iptal edildi.

Ve eğer aşağıdaki kodu çalıştırırsam, hata alıyorum:

CREATE TABLE [testtable]
(Id INT NULL)

Ancak, CREATE TABLESQL Server 2016'da ilke etkinken herhangi bir ifade çalıştırırsam şu hatayı alıyorum:

'Tablo Adları' ilkesi 'SQLSERVER: \ SQL \ LSRSQL07 \ SQL2016 \ Databases \ test \ Tables \ dbo.testtable' tarafından ihlal edildi. Bu işlem geri alınacak. Politika koşulu: '@Ad GİBİ DEĞİL'%% '' Politika açıklaması: '' Ek yardım: '': '' Açıklama: 'CREATE TABLE [testtable] (Id INT NULL)'. Msg 515, Seviye 16, Durum 2, Prosedür sp_syspolicy_execute_policy, Satır 69 [Toplu Başlangıç ​​Satırı 44] NULL değeri 'target_query_expression', table 'msdb.dbo.syspolicy_policy_execution_history_details_internal' sütununa eklenemiyor; sütunu null değerlerine izin vermez. INSERT başarısız. Açıklama sona erdirildi.

SQL Server 2016'da, koşulu geçip geçmediği herhangi bir tablo oluşturamıyorum .

Bu SQL Server 2016, SP1, CU3.

Bu konuda bir fikrin var mı?

Düzenleme: Değerlendirme modunda "Değişiklik: önlemek" olması gerekiyor

Yanıtlar:


6

Komut dosyaları bir SQL Server 2016 SP1 CU2 örneğinde test edilmiştir ve Değerlendirme modu "Değişiklik: Önleme" olarak ayarlanmışsa, ilke çalışır. ( belirli yönleri kullanan politikaları değerlendirmenize izin vermeyen bir hata var).

Bu arada, yalnızca tablo adları için ilkeyi kullanırsanız, aynı yapılandırmayla ( @NAME NOT LIKE '% %') "MultipartName" yerine "Tablo Seçeneği" fasetini de deneyebilirsiniz .


Değerlendirme modunu "İstek Üzerine" olarak ayarlarsam, işe yarar, ancak adil olmak gerekirse, bunu daha önce denememiştim. Bu değişiklik olduğunda: insanların tablo oluşturmasını ve sonra kötü adlandırılmış tablolara başvuruda saklanan procs saklamak için tercih ederim.
John

Benim için değerlendirme modunu "İsteğe bağlı" olarak ayarlamak ve politikayı manuel olarak değerlendirmek işe yaramaz. Ancak, değerlendirme "Değişiklik: Önleme" olarak ayarlanmışsa ve tablo oluşturmaya çalışırsa iyi çalışır. Bir hata olup olmadığını öğrenmek için sorunu Microsoft Connect'te yayınlamayı deneyebilirsiniz.
Dragos

Teşekkürler @Dragos. Herhangi bir masada oluyor, koşulu geçmesi gerekenler bile?
John

Adında boşluk içermeyen tablolar başarıyla oluşturulur ve boşluk içeren tablolar bir politika ihlali hatasıyla başarısız olur.
Dragos

Saklı yordam ve görünüm yönleriyle aynı sorunu yaşıyoruz. SQL 2016 SP1 CU3'te (Son). John'un belirttiği gibi, bu bir hata gibi görünüyor, ancak bir çözüm bulabildiğini merak ediyor muydu?
DBAuser
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.