Par spécification, chaque tableau utilise un guid comme clé primaire. Une autre exigence est que chaque ressource nécessite un identifiant de numéro 6 (100001, 100002, ...) en tant qu'iche publique unique au sein du client qui possède la ressource (liée via Resource -> Location -> Customer
).
J'ai essayé de définir ce numéro 6 à l'aide d'un autre déclencheur. La logique fonctionne bien mais provoque des impasses lorsque je simuler de nombreux inserts entrants. Je peux éliminer cette impasse en ajoutant un tablockx
indice à l'insert. Cependant, puisque LINQ2SQL sera utilisé pour insérer des données, je voudrais éviter d'ajouter une indication de verrouillage à l'insert. J'espérais qu'une combinaison de conseils de verrouillage ou d'indexations d'index dans la gâchette pourrait fonctionner à la place.
Le schéma:
CREATE TABLE [Resource] (
[pkGUID] UNIQUEIDENTIFIER NOT NULL,
[nIdentifier] INT NOT NULL DEFAULT 0,
[fkLocation] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [PK_Resource] PRIMARY KEY CLUSTERED ([pkGUID] ASC)
)
CREATE TABLE [Location] (
[pkGUID] UNIQUEIDENTIFIER NOT NULL,
[fkCustomer] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [PK_Location] PRIMARY KEY CLUSTERED ([pkGUID]
)
CREATE TABLE [Customer] (
[pkGUID] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED ([pkGUID]
)
Actuellement, il n'y a pas d'index sur la table Resource
sauf la clé primaire en cluster.
La gâchette:
CREATE TRIGGER [dbo].[Trigger_Resource_Insert]
ON [dbo].[Resource]
FOR INSERT
AS
BEGIN
SET NoCount ON
;with relevantCustomers as (
select c.pkGUID
from inserted i
join Location l on i.fkLocation = l.pkGUID
join Customer c on l.fkCustomer = c.pkGUID
group by c.pkGUID
), maxNumbers as (
select rc.pkGUID, max = case when max(x.nIdentifier) < 100000 then 100000 else max(x.nIdentifier) end
from relevantCustomers rc
join Location l on l.fkCustomer = rc.pkGUID
join Resource x on x.fkLocation = l.pkGUID
group by rc.pkGUID
), numbers as (
select i.pkGUID, number = row_number() over (partition by n.pkGUID order by i.pkGUID) + n.max
from inserted i
join Location l on i.fkLocation = l.pkGUID
join maxNumbers n on n.pkGUID = l.fkCustomer
)
update x
set nIdentifier = n.number
from Resource x
join numbers n on x.pkGUID = n.pkGUID
END
Un insert générant un tas de données:
;with x as (
select num = 1
union all
select x.num + 1
from x
where x.num < {0}
), l as (
select top {1} fkLocation = pkGUID, sLocationName from Location order by sLocationName
)
insert into Resource with (tablockx) (pkGUID, fkLocation, ...)
select newid(), l.fkLocation, ...
from x
cross join l
Graphique de blocage du profileur SQL lors de l'exécution d'inserts sans tablockx
indice:
Je dois dire que je ne suis pas tout à fait d'accord avec certains des commentaires qui indiquent que ce que vous voyez est nécessairement un problème de cadre. Le livre LINQ vers SQL le plus certainement vous permet de spécifier une procédure stockée comme moyen d'entrée pour les lignes.
Cela étant dit, je vous recommande vivement d'utiliser ce mécanisme au lieu d'une gâchette si possible. Vous pourrez ajouter vos indices de verrouillage à l'intérieur de la procédure stockée et vos inserts fonctionneront bien.
Votre spec, cependant semble très méfiant pour moi et les problèmes que vous semblez courir en ce moment sont de bons contre-extexamples quant à la raison pour laquelle on pourrait ne pas vouloir poursuivre une conception comme celle-ci. Donc, ma question (purement rhétorique) est pour le concepteur. Quel est le numéro séquentiel problématique censé représenter? Si c'est une séquence dans le temps, alors pourquoi ne pas simplement utiliser un temps et utiliser les fonctions de la fenêtre pour commander les lignes dans quelque chose comme une vue à la place (vous pouvez pointer Linq sur SQL sur des vues)? L'intention d'avoir une sorte de numéro séquentielle sans interruption? Êtes-vous connecté à toute la complexité et de verrouillage que vous allez avoir à gérer simplement pour maintenir ce nombre?
Malheureusement, je pense qu'il n'y a pas de réponse réelle - aucune combinaison magique de notes qui fonctionnera sur vos cadres et vos conceptions - qui résoudra votre problème. Imo ma réponse est de retour et regardez de manière critique à votre conception.
on dirait que trop de code pour une gâchette.
reculons et regardons ce que vous essayez d'atteindre.
vous souhaitez définir Nentier pour aucun enregistrement que vous avez inséré.
ma solution serait de ne pas utiliser de déclencheur du tout, c'est-à-dire.