Я хотел бы создать настраиваемое удостоверение на основе настраиваемого удостоверения. Или, возможно, что-то похожее на идентификатор, который функционирует как автоматически увеличивающийся ключ.
Например, если у меня есть первичный ключ для чертежа, я бы хотел, чтобы его версия основывалась на номере чертежа.
Пример
DRAWING ID | REV | INFO ------+-------+------ 1 | 0 | "Draw1" 2 | 0 | "Draw2" 2 | 1 | "Draw2Edit" 2 | 2 | "Draw2MoreEdit" 3 | 0 | "Draw3" 4 | 0 | "Draw4"
] Если бы я вставил еще несколько записей в свою таблицу, например:
INSERT INTO DRAWING (INFO) VALUES ("Draw5")
INSERT INTO DRAWING (ID,INFO) VALUES (3,"Draw3Edit")
Моя таблица должна была бы выглядеть так:
DRAWING ID | REV | INFO ------+-------+------ 1 | 0 | "Draw1" 2 | 0 | "Draw2" 2 | 1 | "Draw2Edit" 2 | 2 | "Draw2MoreEdit" 3 | 0 | "Draw3" 3 | 1 | "Draw3Edit" --NEW ROW 4 | 0 | "Draw4" 5 | 0 | "Draw5" --NEW ROW
T-SQL
CREATE TABLE DRAWING
(
ID INT,
REV INT,
INFO VARCHAR(50),
PRIMARY KEY (ID,REV)
);
CREATE TABLE CURRENT_DRAWING
(
ID INT IDENTITY (1,1),
DRAWING_ID INT,
DRAWING_REV INT,
PRIMARY KEY (ID),
FOREIGN KEY (DRAWING_ID,DRAWING_REV) REFERENCES DRAWING (ID,REV)
ON UPDATE CASCADE
ON DELETE CASCADE
);
Я использую SQL Server Management Studio 2005 и работаю над a База данных SQL Server 2000
Я также приму возможные альтернативы. Основная цель - автоматическое увеличение идентификатора для новых чертежей. Идентификатор останется прежним, а REV будет увеличиваться при новых версиях чертежа.
Я думаю, что это близко к тому, что я хочу:
DROP TABLE DRAW
GO
CREATE TABLE DRAW
(
ID INT DEFAULT(0),
REV INT DEFAULT(-1),
INFO VARCHAR(10),
PRIMARY KEY(ID, REV)
)
GO
CREATE TRIGGER TRIG_DRAW ON DRAW
FOR INSERT
AS
BEGIN
DECLARE @newId INT,
@newRev INT,
@insId INT,
@insRev INT
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
BEGIN TRANSACTION
SELECT @insId = ID FROM inserted
SELECT @insRev = REV FROM inserted
PRINT 'BEGIN TRIG'
PRINT @insId
PRINT @insRev
PRINT @newId
PRINT @newRev
--IF ID=0 THEN IT IS A NEW ID
IF @insId <=0
BEGIN
--NEW DRAWING ID=MAX+1 AND REV=0
SELECT @newId = COALESCE(MAX(ID), 0) + 1 FROM DRAW
SELECT @newRev = 0
END
ELSE
--ELSE IT IS A NEW REV
BEGIN
--CHECK TO ENSURE ID EXISTS
IF EXISTS(SELECT * FROM DRAW WHERE ID=@insId AND REV=0)
BEGIN
PRINT 'EXISTS'
SELECT @newId = @insId
SELECT @newRev = MAX(REV) + 1 FROM DRAW WHERE ID=@insID
END
ELSE
--ID DOES NOT EXIST THEREFORE NO REVISION
BEGIN
RAISERROR 50000 'ID DOES NOT EXIST.'
ROLLBACK TRANSACTION
GOTO END_TRIG
END
END
PRINT 'END TRIG'
PRINT @insId
PRINT @insRev
PRINT @newId
PRINT @newRev
SELECT * FROM DRAW
UPDATE DRAW SET ID=@newId, REV=@newRev WHERE ID=@insId
COMMIT TRANSACTION
END_TRIG:
END
GO
INSERT INTO DRAW (INFO) VALUES ('DRAW1')
INSERT INTO DRAW (INFO) VALUES ('DRAW2')
INSERT INTO DRAW (ID,INFO) VALUES (2,'DRAW2EDIT1') --PROBLEM HERE
INSERT INTO DRAW (ID,INFO) VALUES (2,'DRAW2EDIT2')
INSERT INTO DRAW (INFO) VALUES ('DRAW3')
INSERT INTO DRAW (INFO) VALUES ('DRAW4')
GO
--SHOULD THROW
INSERT INTO DRAW (ID,INFO) VALUES (9,'DRAW9')
GO
SELECT * FROM DRAW
GO
Однако я продолжаю получать Нарушение ограничения PRIMARY KEY
.
Я добавил операторы отладки и кажется маловероятно, что я нарушаю свой первичный ключ:
BEGIN TRIG 0 -1 END TRIG 0 -1 1 0 (1 row(s) affected) (1 row(s) affected) (1 row(s) affected) BEGIN TRIG 0 -1 END TRIG 0 -1 2 0 (2 row(s) affected) (1 row(s) affected) (1 row(s) affected) BEGIN TRIG 2 -1 EXISTS END TRIG 2 -1 2 1 (3 row(s) affected) Msg 2627, Level 14, State 1, Procedure TRIG_DRAW, Line 58 Violation of PRIMARY KEY constraint 'PK__DRAW__56D3D912'. Cannot insert duplicate key in object 'DRAW'. The statement has been terminated.
Он печатает
ID | REV | INFO ----+--------+------------ 1 | 0 | DRAW1 2 | -1 | DRAW2EDIT1 --This row is being updated to 2 1 2 | 0 | DRAW2
Непосредственно перед тем, как он выходит из строя, и строка 2 -1 обновляется до 21. Это не должно нарушать мой первичный ключ.