2016-11-09 6 views
1

SQL Serverストアドプロシージャでカスケード挿入を実行しています。次に、最初のテーブル挿入のIDからSCOPE_IDENTITYを2番目のテーブルに渡します。カスケードインサートでnull Scope_Indentityを解決するにはどうすればよいですか?

しかし、ストアドプロシージャの実行中に、私はSCOPE_IDENTITYのためのNULL値を取得する:

メッセージ515、レベル16、状態2、手順InsertDDM_UserProfile、ライン43
は列「フィルターにNULL値を挿入することはできません'、テーブル' ..... dbo.DDM_Dashboard ';列はNULLを許可しません。 INSERTは失敗します。

質問:なぜストアドプロシージャがSCOPE_IDENTITYを使用してヌルIDを返すのですか?

これは私が作成したストアドプロシージャです。 FK制約はすでにテーブル用に設定されています:

ALTER PROCEDURE [dbo].[InsertDDM_UserProfile] 
    @p_email VARCHAR(100), 
    @p_dashboardName VARCHAR(100), 
AS 
BEGIN  
    INSERT INTO [dbo].[DDM_User] ([Email]) 
    VALUES (@p_email) 

    INSERT INTO [dbo].[DDM_Dashboard] ([Dashboard_Name], [DDM_USER_ID]) 
    VALUES (@p_dashboardName, SCOPE_IDENTITY()) 
END 

そして以下は、二つのテーブルの構造です:

DDM_User-

CREATE TABLE [dbo].[DDM_User] 
(
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Email] [varchar](80) NOT NULL, 

    CONSTRAINT [PK_DDMUser] 
     PRIMARY KEY CLUSTERED ([ID] ASC) 
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

DDM_Dashboard:

CREATE TABLE [dbo].[DDM_Dashboard] 
(
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Dashboard_Name] [varchar](100) NOT NULL, 
    [DDM_USER_ID] [int] NOT NULL, 

    CONSTRAINT [PK_DDMDashboard] 
     PRIMARY KEY CLUSTERED ([ID] ASC) 
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

ALTER TABLE [dbo].[DDM_Dashboard] WITH NOCHECK 
    ADD CONSTRAINT [FK_DDMDashboard_DDMUser] 
     FOREIGN KEY([DDM_USER_ID]) REFERENCES [dbo].[DDM_User] ([ID]) 
GO 

ALTER TABLE [dbo].[DDM_Dashboard] CHECK CONSTRAINT [FK_DDMDashboard_DDMUser] 
GO 
+1

両方のテーブルのテーブルスキーマを確認できますか? DDM_DashboardのFilter列はNullを許可しておらず、insert文にはありません。 –

+0

確かに私はそれを投稿します。 –

答えて

2

です2番目の挿入時にSCOPE_IDENTITY()とは関係ありません。

INSERT INTO [dbo].[DDM_Dashboard] ([Dashboard_Name], [DDM_USER_ID]) 
VALUES (@p_dashboardName, SCOPE_IDENTITY()) 

[Dashboard_Name][DDM_USER_ID]の2つの列にのみ挿入します。エラーメッセージからNULL値を許可しないため、挿入が失敗する列[Filter]の値を指定しないでください。

+0

ええええええええええええええええええええええええええええええええええええええええええええええええええええええんだんだんだんだんだんだんだんだんだんじんだんだんじんだんだんじんだんだんじんだんだんだんじんだんだんじんだんじん –

+0

はい、フィルタ列は実際にはまだテーブルにありました。この列の以前のドロップは、このゴースト列がまだテーブルスキーマに残っていることを意味していませんでした。 –

1
DECLARE @Value1 varchar(50) = 'Test1', @Value2 varchar(50) = 'Test2'; 

DECLARE @Table1 table (Id int NOT NULL IDENTITY(1,1), Value varchar(50) NOT NULL); 
DECLARE @Table2 table (Id int NOT NULL, Value varchar(50) NOT NULL); 

INSERT INTO @Table1 (Value1) 
OUTPUT inserted.Id, @Value2 INTO @Table2 (Id, Value) 
Values (@Value1) 
; 

SELECT * FROM @Table1; 
SELECT * FROM @Table1; 

編集: GarethDが指摘したように、これは実際に起因する外部キー制約の問題に対する有効な解決策ではありません。しかし、他のシナリオでは、両方のレコードのアトミック操作であるため、カスケード挿入と更新を処理するのに便利です。

+1

少しの説明がこれを助けるでしょう。私はあなたが何を得ているのか分かっていると思いますが、残念ながらこの場合、外部キー関係のために 'OUTPUT'節を使って直接2番目のテーブルに挿入することはできませんでした。 'SCOPE_IDENTITY()'の代わりに一時テーブルで 'OUTPUT'を使用してください。外部キーがない場合、または複数の行を挿入する場合、これは間違いなく前進する方法です。 – GarethD

+0

優秀な点、私は制約について忘れてしまった。 – Russ

関連する問題