2

System.Data.SqlClient.SqlException(0x80131904):UNIQUEKEY制約'AK_SeqNo'の違反。オブジェクト'dbo.SeqNo'に重複するキーを挿入できません。

上記のSQLServer2005Expressエラーがランダムに発生します。おそらく、以下のストアドプロシージャから3週間に1回です。誰もが理由を見ることができますか?

CREATE PROCEDURE [dbo].[mspResetSeqNo] @Today DATETIME
AS 
BEGIN
  SET NOCOUNT ON;

  DECLARE @DateSrc DATETIME
  DECLARE @MyGUID UNIQUEIDENTIFIER

  -- Check Input is Valid
  IF @Today IS NULL 
     BEGIN
           RAISERROR (N'@Today cannot be NULL', 10, 1); 
           RETURN 1;
     END

  -- Chop off the time part:
  SET @DateSrc = DATEADD(d, 0, DATEDIFF(d, 0, @Today));

  -- Get Current Location GUID
  SET @MyGUID = dbo.MyGUID();

  -- If this is the first entry for the day then initialise
  INSERT INTO dbo.SeqNo(MyGUID, TheDay, LastNo)
  SELECT @MyGUID, @DateSrc, 0
  WHERE NOT EXISTS ( 
      SELECT 1 FROM dbo.SeqNo AS sn
      WHERE sn.MyGUID = @MyGUID AND sn.TheDay = @DateSrc 
      );

  RETURN(0);
END

AK_SeqNoの制約は次のとおりです。

ALTER TABLE [dbo].[SeqNo] ADD CONSTRAINT [AK_SeqNo] UNIQUE NONCLUSTERED 
(
[TheDay] ASC,
[MyGUID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

これら2つのデータ型のテーブル列は次のとおりです。

[MyGUID] [dbo].[DForeignKey] NOT NULL,
[TheDay] [datetime] NOT NULL,

ユーザー定義型DForeignKeyは次のとおりです。

CREATE TYPE [dbo].[DForeignKey] FROM [uniqueidentifier] NULL

MyGUID()関数は、単にローカルシステムIDを取得しています。場所ごとに異なるIDがあります。

CREATE FUNCTION [dbo].[MyGUID]()
RETURNS uniqueidentifier
AS
BEGIN
DECLARE @me as uniqueidentifier
SELECT @me = MyGUID FROM Self
RETURN @me
END
4

2 に答える 2

1

問題は並行性の問題でした。単一インスタンス チェックは、このストアド プロシージャが呼び出されたコード内のポイントの後に移動されました。ご協力いただきありがとうございます。少なくとも、t-sql 関数についてさらに 2 つ学びました。

于 2013-02-15T06:02:06.827 に答える
0

レコードがテーブルに追加される唯一の方法ですか?

CONVERTまた、次のようなものを比較に使用します。

  INSERT INTO dbo.SeqNo(MyGUID, TheDay, LastNo)
  SELECT @MyGUID, @DateSrc, 0
  WHERE NOT EXISTS ( 
      SELECT 1 FROM dbo.SeqNo AS sn
      WHERE sn.MyGUID = @MyGUID
      AND
      CONVERT(VARCHAR(11), sn.TheDay, 101) = CONVERT(VARCHAR(11), @Today, 101)
      );

これにより、中間値を変数に格納する必要がなくなります。

于 2013-02-13T23:26:46.187 に答える