2011-07-22 2 views
4

私はこのトリガーで間違いを犯してしまいました。私はこのトリガーを追加する前に、データベースの細かいデータを挿入するasp.net/c#アプリケーションのLINQ to SQLデータレイヤーを使用しています。SQL Triggerがnull値を挿入しようとしていますが、C#コードがint 300を渡していますか?

データレイヤーに渡される値は、デバッガでもチェックされているので、完全に有効です。

私は、マイレージの費用が年間10,000ユーロの限界を超えているかどうかを評価しようとしています。ここで

は私のトリガーはあまりコードを貼り付けるための

USE [Horizon] 
GO 
/****** Object: Trigger [dbo].[trER_InsteadOf_Insert] Script Date: 07/22/2011 12:21:44 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author:  Matthew Arnold 
-- Create date: 19/07/2011 
-- Description: Validate Expense Row for Allowed Mileage 
-- ============================================= 
ALTER TRIGGER [dbo].[trER_InsteadOf_Insert] 
    ON [dbo].[ExpenseRow] 
    INSTEAD OF INSERT 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    DECLARE @WorkerID varchar(20); 
    DECLARE @ExpenseID int; 
    DECLARE @Mileage int; 
    DECLARE @Miles int; 
    DECLARE @TotalMiles int; 
    DECLARE @MilesOver10k int; 
    DECLARE @MilesUnder10k int; 
    DECLARE @Amount decimal (7, 2); 
    DECLARE @AmountOver decimal(7, 2); 
    DECLARE @ClaimedDate datetime; 
    DECLARE @HighRateMileage decimal (7, 2); 
    DECLARE @LowRateMileage decimal (7, 2); 

    --Get current mileage and additional miles to work out threshold for worker expense 
    SET @ExpenseID = (SELECT Expense_ID FROM inserted) 
    SET @WorkerID = (SELECT Worker_ID FROM Expense WHERE Expense_ID = @ExpenseID) 
    SET @Mileage = (SELECT Mileage FROM WorkerSettings WHERE Worker_ID = @WorkerID) 
    SET @Miles = (SELECT Mileage FROM inserted) 
    SET @ClaimedDate = (SELECT ExpenseDate From inserted) 

    SET @HighRateMileage = (SELECT Value FROM dbo.SystemSettings WHERE ConfigType_ID = 1 
          AND @ClaimedDate >= StartDate 
          AND @ClaimedDate <= EndDate) 
    SET @LowRateMileage = (SELECT Value FROM dbo.SystemSettings WHERE ConfigType_ID = 2 
          AND @ClaimedDate >= StartDate 
          AND @ClaimedDate <= EndDate) 

    SET @TotalMiles = @Mileage + @Miles 
    SET @MilesOver10k = @TotalMiles - 10000 
    SET @MilesUnder10k = @Miles - @MilesOver10k 

      IF (@Mileage < 10000) 
       BEGIN 
        IF (@TotalMiles > 10000) 
         BEGIN 
          SET @AmountOver = @MilesOver10k * @LowRateMileage 
          SET @Amount = @MilesUnder10k * @HighRateMileage 

          --Split higher rate and lower rate mileage and insert two expense rows 
          INSERT INTO dbo.ExpenseRow (Expense_ID, JobNumber, ExpenseType_ID, Mileage, 
                 ExpenseDate, Description, Amount, Notes, ClientChargeable, 
                 VAT_Receipt, ItemAuthorised, AuthBy, 
                 CreatedBy, CreatedOn, ModifiedBy, ModifiedOn) 

          SELECT Expense_ID, JobNumber, ExpenseType_ID, @MilesOver10k, ExpenseDate, 
                 Description, @AmountOver, 'Calculated at' + ' ' + @LowRateMileage + ' ' + 'pence per mile', 
                 ClientChargeable, 
                 VAT_Receipt, 0, AuthBy, 
                 CreatedBy, CreatedOn, ModifiedBy, ModifiedOn FROM inserted 



          INSERT INTO dbo.ExpenseRow (Expense_ID, JobNumber, ExpenseType_ID, Mileage, 
                 ExpenseDate, Description, Amount, Notes, ClientChargeable, 
                 VAT_Receipt, ItemAuthorised, AuthBy, 
                 CreatedBy, CreatedOn, ModifiedBy, ModifiedOn) 

          SELECT Expense_ID, JobNumber, ExpenseType_ID, @MilesUnder10k, ExpenseDate, 
                 Description, @Amount, 'Calculated at' + ' ' + @HighRateMileage + ' ' + 'pence per mile', 
                 ClientChargeable, 
                 VAT_Receipt, 0, AuthBy, 
                 CreatedBy, CreatedOn, ModifiedBy, ModifiedOn FROM inserted 


         END 
        ELSE 
         BEGIN 
          --Insert higher rate into the expense row 
          INSERT INTO dbo.ExpenseRow (Expense_ID, JobNumber, ExpenseType_ID, Mileage, 
                 ExpenseDate, Description, Amount, Notes, ClientChargeable, 
                 VAT_Receipt, ItemAuthorised, AuthBy, 
                 CreatedBy, CreatedOn, ModifiedBy, ModifiedOn) 

          SELECT Expense_ID, JobNumber, ExpenseType_ID, Mileage,ExpenseDate, 
                 Description, Amount, 'Calculated at' + ' ' + @HighRateMileage + ' ' + 'pence per mile', 
                 ClientChargeable, 
                 VAT_Receipt, 0, AuthBy, 
                 CreatedBy, CreatedOn, ModifiedBy, ModifiedOn FROM inserted 


         END 

       END 


      ELSE 

        BEGIN 
         SET @AmountOver = @MilesOver10k * @LowRateMileage 

          --Insert lower rate mleage into the expense row 
          INSERT INTO dbo.ExpenseRow (Expense_ID, JobNumber, ExpenseType_ID, Mileage, 
                 ExpenseDate, Description, Amount, Notes, ClientChargeable, 
                 VAT_Receipt, ItemAuthorised, AuthBy, 
                 CreatedBy, CreatedOn, ModifiedBy, ModifiedOn) 

          SELECT Expense_ID, JobNumber, ExpenseType_ID, @Mileage,ExpenseDate, 
                 Description, @AmountOver, 'Calculated at' + ' ' + @LowRateMileage + ' ' + 'pence per mile', 
                 ClientChargeable, 
                 VAT_Receipt, 0, AuthBy, 
                 CreatedBy, CreatedOn, ModifiedBy, ModifiedOn FROM inserted 


        END 




END 

申し訳ありませんが、私はここに困惑していますが、経験の私の不足が明らかにこのエラーを作成しました。

あなたは私の問題を見つけられませんか?

おかげ

+0

どのようなエラーが表示されますか? – christofr

+0

nullのフィールドであるため、値nullを列のマイレージに追加することはできませんが、値はデータレイヤーによって渡された一時挿入されたテーブルからのものです – dotnetnewb

+0

どちらのフィールドがヌルになっていますか? – hoodaticus

答えて

7

あなたのトリガーでこのラインを持っている:

SET @Mileage = (SELECT Mileage FROM WorkerSettings WHERE Worker_ID = @WorkerID) 

ので@WorkerIDnullであるか、存在しない場合は、その後、@Mileageはあなたが渡されてきた場合でもnullになってしまうために起こっていますそのための適切な値で。このため、INSERTはトリガーなしで動作します。

+0

私は正しいトラックに私を入れて、歓迎 – dotnetnewb

1

挿入されるExpenseIDに関連付けられたWorkerIDがWorkerSettingsのMilageでNULLでないことを確認します。

+0

はい、それは私の問題の一部だった、ありがとう! – dotnetnewb

2

トリガーを最適に開発してデバッグする方法を教えてください。

ファーストは次にトリガー、挿入、削除が持っているであろうと、データだろう一時テーブルにmulitpleレコードを挿入「#insertedおよび/または#DELETED

ためtemptablesを作成します。必要なすべてのテストケースをカバーするようにしてください。たくさんのレコードがあることは非常に重要です。

次に、コードを挿入する代わりに#insertedを使用して記述します。

これで、最後の操作の前にステップで実行してデータをチェックすることができます。コードを正しく取得するまで、自動的にロールバックできるトランザクションにすべてを入れることもできます。

最後に、これをコメントで述べましたが、一度に1つのレコードしか処理されないと仮定してトリガーを書き込むことはありません。

一度正しい場合は、テンポラリテーブルの名前を挿入または削除し、作成トリガコードを追加します。

+0

入力してくれてありがとう、私は実際には私は現在のdeailでSQL ServerとC#の周りに多くの仕事をしていない。どんなアドバイスもありがとうございます。ありがとうございます! – dotnetnewb

+0

上記のすべてのデータ型とテーブルを使用してこのトリガを書く方法を知りたいと思っています。 – dotnetnewb

関連する問題