2010-01-11 78 views
2

主鍵我有一個表,看起來像這樣:違反了select語句

CREATE TABLE [dbo].[SomeTable](
    [Guid] [uniqueidentifier] NOT NULL, 
    [Column1] [int] NOT NULL, 
    [Column2] [datetime] NOT NULL, 
    [Column3] [bit] NOT NULL, 
    [Column4] [smallint] NOT NULL, 
    [Column5] [uniqueidentifier] NULL, 
    [Column6] [varchar](100) NULL, 
    [Column7] [datetime] NULL, 
    [Column8] [datetime] NULL, 
CONSTRAINT [pkSomeTable] PRIMARY KEY CLUSTERED 
(
    [Guid] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY] 
) 

注:該名稱已被更改,以保護無辜。

通過存儲過程,我運行此查詢:

SELECT SomeTable.Guid, SomeTable.Column1, SomeTable.Column2, SomeTable.Column3, SomeTable.Column4, SomeTable.Column5, SomeTable.Column6, SomeTable.Column7, SomeTable.Column8 
     FROM SomeTable 
     WHERE SomeTable.Guid = @Guid 
     ORDER BY SomeTable.Guid 

運行在此之後,我得到一個:PRIMARY KEY約束 'pkSomeTable' 的 衝突。無法在對象'dbo.SomeTable'中插入重複鍵。 UniqueKeyConstraintException:重複鍵。

我很困惑我如何能有這樣的異常只運行一個選擇語句。桌子上沒有觸發器。有沒有人有這樣的想法?

編輯: 整個STP是:

CREATE PROCEDURE dbo.stpSelectSomeTable 
     @Guid UNIQUEIDENTIFIER = NULL 
    AS 
    BEGIN 
    SET NOCOUNT ON 

    IF (@Guid is NULL) 

     SELECT SomeTable.Guid, SomeTable.Column1, SomeTable.Column2, SomeTable.Column3, SomeTable.Column4, SomeTable.Column5, SomeTable.Column6, SomeTable.Column7, SomeTable.Column8 
     FROM SomeTable 
     ORDER BY SomeTable.Guid 

    Else 

     SELECT SomeTable.Guid, SomeTable.Column1, SomeTable.Column2, SomeTable.Column3, SomeTable.Column4, SomeTable.Column5, SomeTable.Column6, SomeTable.Column7, SomeTable.Column8 
     FROM SomeTable 
     WHERE SomeTable.Guid = @Guid 
     ORDER BY SomeTable.Guid 

END 
GO 

我相信GUID不爲空時,該STP被調用。我也確信這是導致問題的陳述。異常的堆棧跟蹤顯示了這一點。事實證明,發生這種情況的數據庫已被刪除並恢復到以前的版本。正因爲如此,我無法測試這個陳述。這是在給我這個問題之前完成的。

+1

雙重和三重檢查導致PK違規的聲明。 是什麼讓你認爲這是SELECT語句? – 2010-01-11 15:04:30

+3

您確定此聲明導致錯誤?您能否單獨運行此聲明以查看問題是否存在?你能不能發佈整個sproc源代碼? – Quassnoi 2010-01-11 15:04:36

+0

存儲過程還有什麼作用?你可以顯示存儲過程的所有代碼,以及你如何調用它? – 2010-01-11 15:08:29

回答

2

我懷疑你誤解了SQL錯誤消息,告訴你它檢測到錯誤的行。

行號將相對於發生錯誤的查詢批處理的開始。 GO用作批量分離器。因此,具有1行

/*A comment 
Next line starts a new batch*/ 
GO 
INSERT INTO T1 VALUES(1) 

發生了下面的例子在INSERT一個PK錯誤將被報告爲大多數肯定的評論是不負責的PK違反。

編輯 要跟蹤問題,可以通過註釋掉不相關的部分來運行腳本「零食」部分。

+0

我正在談論C#應用程序中的堆棧跟蹤。它與SQL Server報告的行號沒有任何關係。 – Bryan 2010-01-11 15:25:11

+0

在這種情況下,我建議您運行SQL Server Profiler來檢查正在執行的查詢/ procs。 C#正在拾取錯誤,但是其他內容正在導致錯誤。 – 2010-01-11 15:35:19

3

我剛剛嘗試過上面發佈的SQL,沒有違反PK的規定,所以別人指出,這個語句本身沒有問題,所以它必須在其他地方。

至於如何解決該問題,您可以嘗試使用SQL分析器創建一個跟蹤,然後運行SP。這應該可以幫助你找出導致PK違規的語句正在發生的地方。您需要安裝SQL分析器才能使用此功能。這裏是一個鏈接的更多信息: http://technet.microsoft.com/en-us/library/ms175047.aspx

1

另一個想法......你確定這是你正在調用的存儲過程嗎?

SQL Server有一些可能導致混淆的事情。例如:單個數據庫可以有多個「模式」。如果你沒有使用慣例調用你的存儲過程,你最終可能會從不同的模式中調用具有相同名稱的過程。

我建議你修改你存儲的proc來打印一個簡單的輸出行來確認那個被調用的。

+0

我們總是用dbo調用存儲過程。前綴。雖然好想。 – Bryan 2010-01-11 15:34:05

0

看起來問題確實是一個插入。不知道爲什麼選擇錯誤作爲導致問題的語句。這是一個線程問題。我們有這樣的代碼:

row = dbo.stpSelectSomeTable @Guid = {SomeGuid} 
if (row exists) 
{ 
    do stuff to update the row 
} 
else 
{ 
    insert new row with {SomeGuid} 
} 

有沒有任何形式的同步這裏,所以多個線程試圖插入一行具有相同GUID的。我們加了一把鎖,一切都很好。

非常感謝您的建議。

+0

其他答案告訴你SELECT不會導致PK違規?你爲什麼不接受其中之一? – 2010-01-22 08:16:20