Puoi eseguire DBCC CHECKCONSTRAINTS
comando console per restituire un elenco di tutte le violazioni dei vincoli in un database di SQL Server.
Questo comando verifica l'integrità di un vincolo specificato o di tutti i vincoli su una tabella specificata nel database corrente. Restituisce qualsiasi chiave esterna e CHECK
violazioni dei vincoli che rileva.
Puoi usare ALL_CONSTRAINTS
opzione per controllare sia i vincoli abilitati che quelli disabilitati. Se lo ometti, vengono restituiti solo i vincoli abilitati (a meno che tu non specifichi esplicitamente un vincolo da controllare, nel qual caso verrà restituito indipendentemente dal fatto che sia abilitato o disabilitato).
Esempio 1 – Vincoli CHECK violati
Ho eseguito questo esempio su un database che contiene alcuni CHECK
violazioni dei vincoli.
USE Test;DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Risultato:
+--------------------------------------+------+- -------------------------------------------------- ------+| tavola | vincolo | Dove ||-------------------------+--------------------+-- -------------------------------------------------- -----|| [dbo].[Occupazione] | [chkTitolo lavoro] | [Titolo lavoro] ='Nomade digitale' || [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2020-01-01' AND [EndDate] ='1999-01-01' || [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2021-10-25' AND [EndDate] ='2021-10-24' |+-----------------------+ -------------------+----------------- ----------------------------+
Questo mostra che ho tre violazioni dei vincoli nel mio database.
Spiegazione delle colonne
Le tre colonne restituiscono le seguenti informazioni:
- Tabella
- Nome del nome della tabella che contiene la violazione del vincolo.
- Vincolo
- Nome del vincolo violato.
- Dove
- Assegnazioni di valori di colonna che identificano la riga o le righe che violano il vincolo. Il valore in questa colonna può essere utilizzato in un
WHERE
clausola di unSELECT
istruzione che esegue query per righe che violano il vincolo.
Pertanto, grazie alla terza colonna, ora posso trovare (e aggiornare) tutti i dati non validi.
Trova i dati non validi
Quindi, se osserviamo la prima riga del mio DBCC CHECKCONSTRAINTS
risultati, vediamo che possiamo trovare i dati offensivi usando [JobTitle] = 'Digital Nomad'
in un WHERE
clausola.
In questo modo:
SELEZIONARE *DA [dbo].[Occupazione]WHERE [Titolo lavoro] ='Nomade digitale';
Risultato:
+----------------+---------------+| ID occupazione | Titolo lavoro ||----------------+---------------|| 7 | Nomade digitale |+----------------+---------------+
La definizione del vincolo
Diamo un'occhiata alla definizione effettiva per il chkJobTitle
vincolo:
SELEZIONA Definizione DA sys.check_constraintsWHERE name ='chkJobTitle';
Risultato:
+-------------------------------+| Definizione ||-----------------||| ([Titolo lavoro]<>'Nomade digitale') |+--------------------------------+
Questo vincolo dice che il valore di JobTitle la colonna deve non essere Nomade digitale , eppure un nomade digitale è comunque riuscito a entrare nel mio database!
Aggiorna i dati illeciti
Puoi aggiornare i dati offensivi, eliminarli o lasciarli soli.
In questo esempio utilizzo lo stesso WHERE
clausola per aggiornare il valore:
UPDATE [dbo].[Occupation]SET [JobTitle] ='Disoccupato'WHERE [JobTitle] ='Digital Nomad';
Ora, se eseguo di nuovo il controllo, quel record non è più un problema e rimangono solo gli altri due problemi:
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Risultato:
+--------------------------------------+------+- -------------------------------------------------- ------+| tavola | vincolo | Dove ||-------------------------+--------------------+-- -------------------------------------------------- -----|| [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2020-01-01' AND [EndDate] ='1999-01-01' || [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2021-10-25' AND [EndDate] ='2021-10-24' |+-----------------------+ -------------------+----------------- ----------------------------+
Esempio 2 – Vincoli di chiave esterna violati
In questo esempio passo a un database che contiene un paio di violazioni dei vincoli di chiave esterna.
USE Music;DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Risultato:
+----------------+--------+-------- -------------+| tavola | vincolo | Dove ||----------------+----------------------+--------- ------------|| [dbo].[Album] | [FK_Album_Artisti] | [ID artista] ='123' || [dbo].[Album] | [FK_Album_Artisti] | [ArtistId] ='17' |+----------------+----------------------+-- ---+
In questo caso, sembra che ci siano due righe negli Album la tabella fa riferimento a un ArtistId quello non esiste.
Trova i dati non validi
Ancora una volta, possiamo usare
Dove
colonna per costruire il nostro WHERE
clausola. Questa volta aggiungerò entrambe le violazioni al mio WHERE
clausola:
SELECT *FROM [dbo].[Album]WHERE [ArtistId] ='123' O [ArtistId] ='17';
Risultato:
+-----------+-------------+---------------+---- --------+------------+| IDAlbum | NomeAlbum | Data di rilascio | ID artista | GenereId ||-----------+-------------+---------------+----- -------+-----------|| 21 | Yo Wassup | 2019-03-12 | 17 | 3 || 22 | sballato | 11-05-1901 | 123 | 3 |+-----------+-------------+---------------+----- -------+-----------+
Quindi ora possiamo vedere le due righe che violano il vincolo (sebbene sia solo ArtistId colonna che viola il vincolo).
Controlla la tabella delle chiavi primarie
Possiamo confermare la violazione interrogando gli Artisti table (ovvero la tabella che contiene la chiave primaria per questa chiave esterna).
Quindi eseguiamo la stessa query sugli Artisti tabella.
SELECT *FROM [dbo].[Artists]WHERE [ArtistId] ='123' OR [ArtistId] ='17';
Risultato:
(0 righe interessate)
Come previsto, nessuno dei due valori è in quella tabella.
La chiave esterna dovrebbe impedire che ciò accada. I dati non validi sono entrati nel database mentre la chiave esterna era disabilitata o sono stati inseriti prima della creazione della chiave esterna. In entrambi i casi, quando si crea o si abilita una chiave esterna o CHECK
vincolo, dovresti usare WITH CHECK
per specificare che tutti i dati esistenti devono essere controllati prima di abilitare il vincolo.
Esempio 3:spunta solo i vincoli abilitati
Se vuoi controllare solo i vincoli attualmente abilitati, rimuovi WITH ALL_CONSTRAINTS
:
Test USE;CONTROLLO VINCOLI DBCC;
Risultato:
+--------------------+---------------+--------- ---------------------+| tavola | vincolo | Dove ||--------------------+---------------+---------- --------------------|| [dbo].[Occupazione] | [chkTitolo lavoro] | [Titolo lavoro] ='Nomade digitale' |+--------------------+---------------+--- ----------------------------+
Quindi, tra i due vincoli che sono stati violati, sembra che chkJobTitle è l'unico abilitato.
Possiamo verificarlo ulteriormente con la seguente query:
SELECT name, is_disabledFROM sys.check_constraintsWHERE name ='chkValidEndDate' OR name ='chkJobTitle';
Risultato:
+-----------------+---------------+| nome | is_disabled ||-----------------+---------------|| chkTitolo lavoro | 0 || chkValidEndDate | 1 |+-----------------+---------------+
Esempio 4 – Verifica solo i vincoli per una determinata tabella
Puoi aggiungere il nome di una tabella tra parentesi se vuoi solo controllare i vincoli per quella tabella:
USE Test;DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;
Risultato:
+--------------------------------------+------+- -------------------------------------------------- ------+| tavola | vincolo | Dove ||-------------------------+--------------------+-- -------------------------------------------------- -----|| [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2020-01-01' AND [EndDate] ='1999-01-01' || [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2021-10-25' AND [EndDate] ='2021-10-24' |+-----------------------+ -------------------+----------------- ----------------------------+
Esempio 5:verifica di un singolo vincolo
Puoi controllare un singolo vincolo racchiudendo il suo nome tra parentesi:
USE Test;DBCC CHECKCONSTRAINTS(chkValidEndDate);
Risultato:
+--------------------------------------+------+- -------------------------------------------------- ------+| tavola | vincolo | Dove ||-------------------------+--------------------+-- -------------------------------------------------- -----|| [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2020-01-01' AND [EndDate] ='1999-01-01' || [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2021-10-25' AND [EndDate] ='2021-10-24' |+-----------------------+ -------------------+----------------- ----------------------------+
Quando specifichi un singolo vincolo, il WITH ALL_CONSTRAINTS
non ha effetto:
USE Test;DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;
Risultato:
+--------------------------------------+------+- -------------------------------------------------- ------+| tavola | vincolo | Dove ||-------------------------+--------------------+-- -------------------------------------------------- -----|| [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2020-01-01' AND [EndDate] ='1999-01-01' || [dbo].[Test Vincolo] | [chkValidEndDate] | [StartDate] ='2021-10-25' AND [EndDate] ='2021-10-24' |+-----------------------+ -------------------+----------------- ----------------------------+