Problema con le convenzioni di denominazione delle tabelle e la gestione dei criteri in SQL Server 2016


10

In SQL Server 2012, avevo una serie di politiche per non consentire spazi nel nome di una tabella. Tuttavia, quando utilizzo lo stesso criterio in SQL Server 2016, viene visualizzato un errore.

Ecco il codice per la condizione:

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

Ecco il codice per la politica:

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

In SQL Server 2012 e 2014, ciò fornisce i risultati previsti:

CREATE TABLE [test table]
(Id INT NULL)

Il criterio "Nomi tabelle" è stato violato da "SQLSERVER: \ SQL \ LSRSQL07 \ SQL2012 \ Database \ test \ Tables \ dbo.test". Questa transazione verrà ripristinata. Condizione della politica: '@NOME NON MI PIACE'% [-.]% 'E @NOME NON MI PIACE'% [^ A-Za-z0-9 [_]]% '' Descrizione della politica: '' Aiuto aggiuntivo: '': '' Dichiarazione: 'CREATE TABLE [tabella test] (Id INT NULL)'. Messaggio 3609, livello 16, stato 1, procedura sp_syspolicy_dispatch_event, linea 65 [Batch Start Line 48] La transazione è terminata nel trigger. Il batch è stato interrotto.

E se eseguo il seguente codice, non ottengo alcun errore:

CREATE TABLE [testtable]
(Id INT NULL)

Tuttavia, se eseguo qualsiasi CREATE TABLEistruzione, con il criterio abilitato, su SQL Server 2016, ottengo il seguente errore:

Il criterio "Nomi tabelle" è stato violato da "SQLSERVER: \ SQL \ LSRSQL07 \ SQL2016 \ Database \ test \ Tables \ dbo.testtable". Questa transazione verrà ripristinata. Condizione politica: '@Nome NON MI PIACE'%% '' Descrizione politica: '' Aiuto aggiuntivo: '': '' Dichiarazione: 'CREATE TABLE [testtable] (Id INT NULL)'. Messaggio 515, livello 16, stato 2, procedura sp_syspolicy_execute_policy, riga 69 [Batch Start Line 44] Impossibile inserire il valore NULL nella colonna "target_query_expression", tabella "msdb.dbo.syspolicy_policy_execution_history_details_internal"; colonna non consente valori null. INSERT non riesce. La dichiarazione è stata chiusa.

In SQL Server 2016, non riesco a creare alcuna tabella , sia che passi la condizione o meno.

Questo è SQL Server 2016, SP1, CU3.

Qualche idea su questo?

Modifica: ho bisogno che la modalità di valutazione sia "On change: prevent"

Risposte:


6

Testato gli script su un'istanza CU2 di SQL Server 2016 SP1 e il criterio funziona se la modalità di valutazione è impostata su "In caso di modifica: Impedisci". (esiste un bug che non ti consente di valutare i criteri che utilizzano aspetti specifici).

Nel frattempo, se si utilizza la politica solo per i nomi delle tabelle, è possibile provare anche il facet "Opzione tabella" anziché "MultipartName", con la stessa configurazione ( @NAME NOT LIKE '% %').


Se ho impostato la modalità di valutazione su "On Demand", funziona, ma per essere onesti, non ci avevo provato prima. Preferirei avere questo Al momento del cambiamento: impedisci di impedire alle persone di creare tabelle e quindi proc memorizza i riferimenti alle tabelle mal denominate.
Giovanni

Per me non funziona impostare la modalità di valutazione su "Su richiesta" e valutare manualmente la politica. Funziona bene se la valutazione è impostata su "In modifica: Impedisci" e prova a creare tabelle. Puoi provare a pubblicare il problema su Microsoft Connect per scoprire se si tratta di un bug o meno.
Dragos,

Grazie @Dragos. Sta accadendo su qualsiasi tavolo, anche quelli che dovrebbero superare la condizione?
Giovanni

Le tabelle che non hanno spazi bianchi nel nome vengono create correttamente e quelle che hanno spazi bianchi non riescono con un errore di violazione dei criteri.
Dragos,

Stiamo riscontrando lo stesso problema con la procedura memorizzata e visualizzare le sfaccettature. Siamo su SQL 2016 SP1 CU3 (più recente). Come ha affermato John, sembra un bug ma si chiedeva se qualcuno fosse in grado di trovare una soluzione?
DBAuser,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.