2014-04-07 64 views
0

我知道使用IDENT_CURRENT不會總是給我返回正確的標識值(在多線程應用程序中尤其如此)。我想用SCOPE_IDENTITY()代替。在約束中使用SCOPE_IDENTITY()

例如,這是我的Employee表:

create table Employee 
(
    ID  int identity(1,1), 
    Name varchar(20), 
    SystemID int, 
    constraint Employee_PK primary key (ID asc) 
) 

我有如下聲明:

alter table Employee 
    add constraint Employee_D1 default ident_current('Employee') for SystemID 

,我需要修改使用SCOPE_IDENTITY()來代替。

我嘗試以下:

alter table Employee 
    add constraint Employee_D1 default SCOPE_IDENITITY() for SystemID 

這並沒有給出任何錯誤。但插入一行後,我沒有看到這個列更新了身份值。我究竟做錯了什麼?

請注意,SystemID不得爲只讀,所以計算字段不是一個選項。

這裏我的練習是在並行進程試圖插入行的情況下,試圖消除在SystemID中輸入錯誤的IDENTITY值。

+0

的問題是與IDENT_CURRENT是值,否則使用它應該是安全的,因爲它爲您提供任何會話的最後一個身份值。 SCOPE_IDENTITY只適用於當前會話,我認爲這就是爲什麼你沒有從中獲得價值。 但我不確定你從這個約束中獲得了什麼好處? –

+0

同意Allan - 擁有默認爲「SCOPE_IDENTITY」的列有什麼意義?如果你的表中需要一個唯一的值 - 使用一個'INT IDENTITY'類型的列 - 但是具有相同值的第二列有什麼好處?如果你必須有這樣的事情 - 你需要使用一個'ON INSERT'觸發器...... –

+0

我很困惑 - 'ID'是_already_一個'IDENTITY'列 - 您是否試圖確保'SystemID'總是等於'ID'?或者在其他表格中添加一個「ID」? –

回答

1

只需重新閱讀您的答案。 SystemID不是標識列。我不認爲你可以使用SCOPE_IDENITITY(),因爲它沒有添加行,並在需要保存值的時候檢索新的Identity值。

你需要做的是創建一個觸發器在插入行後更新SystemId值。 CREATE TRIGGER

+0

如果並行進程正在插入行,「AFTER INSERT」觸發器是否有助於使用正確的標識值更新'SystemID'? – aliensurfer

+0

是的。只要你在你的觸發器中使用插入的表來獲得新的ID。 http://technet.microsoft.com/en-us/library/ms191300.aspx – sarin

0

以下是我想解決這個問題(道歉爲窮人字段名,我覺得不舒服的發明),如果你用它來預測未來

CREATE TABLE employees (
    id    int identity(1,1) NOT NULL 
, name    varchar(20)  NOT NULL 
, actual_system_id int     NULL 
, system_id As Coalesce(actual_system_id, id) 
, CONSTRAINT pk_employees PRIMARY KEY (id) 
) 
; 

INSERT INTO employees (name) 
    VALUES ('John') 
     , ('Paul') 
     , ('George') 
     , ('Ringo') 
; 

SELECT id 
    , name 
    , system_id 
FROM employees 
; 

UPDATE employees 
SET actual_system_id = 937 
WHERE name = 'George' 
; 

SELECT id 
    , name 
    , system_id 
FROM employees 
;