Je conçois un nouveau schéma de base de données pour une base de données SQL Server 2012.
Chaque table doit avoir deux colonnes supplémentaires appelées modified
et created
qui doivent être automatiquement modifiées dès qu'une ligne est insérée ou mise à jour.
Je ne sais pas comment faire le meilleur moyen d'y arriver.
Je suppose que ce déclencheur est le meilleur moyen de le gérer.
J'essayais de trouver des exemples avec des déclencheurs .. mais les tutoriels que j'ai trouvés inséraient des données dans une autre table, etc.
J'ai supposé que c'était un scénario assez courant mais je n'ai pas encore trouvé de réponse.
La colonne created
est simple: il s'agit simplement d'une colonne DATETIME2(3)
avec une contrainte par défaut qui est définie lors de l'insertion d'une nouvelle ligne:
Created DATETIME2(3)
CONSTRAINT DF_YourTable_Created DEFAULT (SYSDATETIME())
Ainsi, lorsque vous insérez une ligne dans YourTable
et que vous ne spécifiez pas de valeur pour Created
, elle sera définie sur la date et l'heure actuelles.
La modified
représente un peu plus de travail, car vous devez écrire un déclencheur pour le cas AFTER UPDATE
et le mettre à jour - vous ne pouvez pas indiquer de manière déclarative à SQL Server de le faire pour vous ....
Modified DATETIME2(3)
et alors
CREATE TRIGGER updateModified
ON dbo.YourTable
AFTER UPDATE
AS
UPDATE dbo.YourTable
SET modified = SYSDATETIME()
FROM Inserted i
WHERE dbo.YourTable.PrimaryKey = i.PrimaryKey
Vous devez rejoindre la pseudo table Inserted
qui contient toutes les lignes qui ont été mises à jour avec votre table de base sur votre clé primaire pour cette table.
Et vous devrez créer ce déclencheur AFTER UPDATE
pour chaque table dans laquelle vous souhaitez placer une colonne modified
.
Généralement, vous pouvez avoir les colonnes suivantes:
où LastModifiedBy
et CreatedBy
sont des références à une table users
(UserID
) et les colonnes LastModifiedOn
et CreatetOn
sont des colonnes de date et d'heure.
Vous avez les options suivantes:
Solution sans déclencheurs - J'ai lu quelque part que "Le meilleur moyen d'écrire des déclencheurs est de ne pas écrire de tels." Et vous devriez savoir qu'en général, ils nuisent à la performance. Donc, si vous pouvez les éviter, il est préférable de le faire, même utiliser des déclencheurs peut sembler la chose la plus facile à faire dans certains cas.
Donc, éditez simplement toutes vos instructions INSERT
et UPDATE
pour inclure la UserID
actuelle et la date et l'heure actuelles. Si un tel user ID
ne peut pas être défini (utilisateur anonyme), vous pouvez utiliser 0
à la place et la valeur par défaut des colonnes (si aucun user ID
n'est spécifié, ce sera NULL
). Lorsque vous voyez les valeurs NULL
insérées, vous devez rechercher les déclarations "coupables" et les modifier.
Solution avec déclencheurs - vous pouvez créer le déclencheur AFTER INSERT, UPDATE
et y renseigner les colonnes des utilisateurs. Il est facile d'obtenir la date et l'heure actuelles dans le contexte du déclencheur (utilisez GETUTCDATE()
par exemple). Le problème ici est que les déclencheurs ne permettent pas de transmettre/accepter des paramètres. Donc, comme vous n'insérez pas la valeur user ID
et que vous ne pouvez pas la transmettre au déclencheur. Comment trouver l'utilisateur actuel?
Vous pouvez utiliser SET CONTEXT_INFO et CONTEXT_INFO . Avant toutes vos instructions insert
et update
, vous devez utiliser le SET CONTEXT_INFO
pour ajouter le current user ID
au contexte actuel. Dans le déclencheur, vous utilisez la fonction CONTEXT_INFO
pour l'extraire.
Ainsi, lorsque vous utilisez des déclencheurs, vous devez à nouveau éditer toutes vos clauses INSERT
et UPDATE
- c'est pourquoi je préfère ne pas les utiliser.
Quoi qu'il en soit, si vous n'avez besoin que de colonnes de date et d'heure et non créées/modifiées par des colonnes, l'utilisation de déclencheurs est plus durable et plus simple, car vous n'éditerez aucune autre instruction maintenant et dans le futur.
Avec SQL Server 2016
, nous pouvons maintenant utiliser la fonction SESSION_CONTEXT pour lire les détails de la session. Les détails sont définis avec sp_set_session_context (sous la forme read-only
ou read and write
). Les choses sont un peu conviviales:
EXEC sp_set_session_context 'user_id', 4;
SELECT SESSION_CONTEXT(N'user_id');
Un Nice exemple .
Attention, ci-dessus fonctionne bien mais pas dans tous les cas, .__ J'ai perdu beaucoup de temps et j'ai trouvé ceci utile:
create TRIGGER yourtable_update_insert
ON yourtable
AFTER UPDATE
as
begin
set nocount on;
update yourtable set modified=getdate(), modifiedby = suser_sname()
from yourtable t
inner join inserted i on t.uniqueid=i.uniqueid
end
go
set nocount on;
est nécessaire sinon vous obtenez l'erreur:
Microsoft SQL Server Management Studio
Aucune ligne n'a été mise à jour.
Les données de la ligne 5 n'ont pas été validées . Source de l'erreur: Microsoft.SqlServer.Management.DataTools . Message d'erreur: Les valeurs de ligne mises à jour ou supprimées ne rendent pas la ligne unique ou modifient plusieurs lignes (2 rangées).
Corrigez les erreurs et réessayez ou appuyez sur ÉCHAP pour annuler les modifications.
OK aide