2

私はトリガーが初めてで、この質問に対する答えが見つからないようです。

テーブルに計算された行を挿入する必要がありますが、アプリケーションのソース コードにはアクセスできません。テーブルにトリガーを作成して、挿入された値に基づいて値を計算し、それらをテーブルに挿入することで回避できると思いましたが、これがどのように機能するかはわかりません。

次のトリガーがあります。更新には機能しますが、挿入には機能しません。「FOR INSERT、UPDATE」の「INSERT」を削除すると、account_id フィールド (唯一の非 null フィールド) が挿入されますが、残りは挿入されません。「INSERT」をそのままにしておくと、どのフィールドも挿入されません。

挿入と更新の両方でこれを機能させるにはどうすればよいですか?

ALTER TRIGGER [dbo].[SelfCalFieldsTrigger]
ON [dbo].[dynTable]
FOR INSERT, UPDATE
AS
BEGIN

Declare @acctID uniqueidentifier
Declare @invDiscPremPerc decimal(9,6)
Declare @investorSRP decimal(9,6)
Declare @purchWireAmt decimal(11,2)

set @acctID = (Select account_id from inserted) 

set @invDiscPremPerc = (Select Coalesce(INVESTOR_DISC_PREM_DOLLAR, 0)/
Coalesce(INVESTOR_PRIN_BAL_PURCHASED, 0)*100 from inserted)


set @investorSRP = (Select Coalesce(INVESTOR_SRP_PREM_DOLLAR, 0)/
Coalesce(INVESTOR_PRIN_BAL_PURCHASED, 0)*100 from inserted)


set @purchWireAmt = (Select Coalesce(INVESTOR_PRIN_BAL_PURCHASED, 0)-
Coalesce(INVESTOR_ADMIN_FEE, 0)-
Coalesce(INVESTOR_WIRE_FEE, 0)- Coalesce(INVESTOR_FLOOD_FEE, 0)-
Coalesce(INVESTOR_TAX_SERVICE_FEE, 0) - Coalesce(INVESTOR_OTHER_FEE, 0) from     
inserted)


UPDATE [dbo].dynTable]
set INVESTOR_DISC_PREM_PERCENT = @invDiscPremPerc,
INVESTOR_SRP = @investorSRP,
PURCHASE_WIRE_AMOUNT = @purchWireAmt
Where [dbo].[dynTable].Account_ID = @acctID

END
4

3 に答える 3

3

トリガーのロジックを変更する必要があります。現時点では、挿入または更新された行が 1 つだけであると想定していますが、そうではありません。INSERTED挿入または更新されたすべての行を含む疑似テーブルです。したがって、代わりにこれを試してください:

ALTER TRIGGER [dbo].[SelfCalFieldsTrigger]
ON [dbo].[dynTable]
FOR INSERT, UPDATE
AS
BEGIN

    UPDATE A
    SET INVESTOR_DISC_PREM_PERCENT = ISNULL(B.INVESTOR_DISC_PREM_DOLLAR / 
                                            NULLIF(B.INVESTOR_PRIN_BAL_PURCHASED,0)*100,0),
    INVESTOR_SRP = ISNULL(B.INVESTOR_SRP_PREM_DOLLAR / 
                          NULLIF(B.INVESTOR_PRIN_BAL_PURCHASED,0)*100,0),
    PURCHASE_WIRE_AMOUNT =  COALESCE(B.INVESTOR_PRIN_BAL_PURCHASED, 0)-
                            COALESCE(B.INVESTOR_ADMIN_FEE, 0)-
                            COALESCE(B.INVESTOR_WIRE_FEE, 0)- 
                            COALESCE(B.INVESTOR_FLOOD_FEE, 0)-
                            COALESCE(B.INVESTOR_TAX_SERVICE_FEE, 0)- 
                            COALESCE(B.INVESTOR_OTHER_FEE, 0)
    FROM [dbo].[dynTable] A
    INNER JOIN INSERTED B
        ON A.Account_ID = B.Account_ID

END
于 2013-09-10T14:11:50.267 に答える
0

上記のコメントに同意します。挿入されたテーブルには、1 ~ n 行を含めることができます。

トリガー以外に2つの提案があります。

ビジネス ロジックをきちんとしたパッケージにまとめる関数を作成できます。

1 - テーブルのデザインを変更して、永続化された計算列を追加できますか?

上記の機能を設計に使用します。

2 - SELECT ステートメントで計算フィールドを使用してビューを作成するのはどうですか?

上記の機能を設計に使用します。

最後になりましたが、ヌル値とゼロ値の両方で機能するトリガー ソリューションです。

--
-- Sample table
--

-- Use temp database
USE TEMPDB;
GO

-- Remove old object
IF OBJECT_ID('DBO.INVESTOR') > 1
    DROP TABLE DBO.INVESTOR
GO

-- Create new object
CREATE TABLE DBO.INVESTOR
(
    INVESTOR_ID INT IDENTITY(1, 1),
    INVESTOR_PRIN_BAL_PURCHASED MONEY,
    INVESTOR_DISC_PREM_DOLLAR MONEY,
    INVESTOR_SRP_PREM_DOLLAR MONEY,
    INVESTOR_ADMIN_FEE MONEY,
    INVESTOR_WIRE_FEE MONEY,
    INVESTOR_FLOOD_FEE MONEY,
    INVESTOR_TAX_SERVICE_FEE MONEY,
    INVESTOR_OTHER_FEE MONEY,
    INVESTOR_DISC_PREM_PERCENT REAL,
    INVESTOR_SRP REAL,
    PURCHASE_WIRE_AMOUNT MONEY
);


--
-- Sample trigger
--

-- Remove old object
IF OBJECT_ID('DBO.CALCULATE_FEILDS') > 1
    DROP TRIGGER DBO.CALCULATE_FEILDS
GO

-- Create new object
CREATE TRIGGER DBO.CALCULATE_FEILDS ON DBO.INVESTOR
FOR INSERT, UPDATE AS
BEGIN

    UPDATE 
        DBO.INVESTOR
    SET 
        INVESTOR_DISC_PREM_PERCENT = 
            CASE WHEN INVESTOR_PRIN_BAL_PURCHASED <> 0 THEN
                Coalesce(INVESTOR_DISC_PREM_DOLLAR, 0) /
                Coalesce(INVESTOR_PRIN_BAL_PURCHASED, 0) * 100
            ELSE 0 END,

        INVESTOR_SRP = 
            CASE WHEN INVESTOR_PRIN_BAL_PURCHASED <> 0 THEN
                Coalesce(INVESTOR_SRP_PREM_DOLLAR, 0) /
                Coalesce(INVESTOR_PRIN_BAL_PURCHASED, 0) * 100
            ELSE 0 END,
        PURCHASE_WIRE_AMOUNT = 
            Coalesce(INVESTOR_PRIN_BAL_PURCHASED, 0) -
            Coalesce(INVESTOR_ADMIN_FEE, 0) -
            Coalesce(INVESTOR_WIRE_FEE, 0) - 
            Coalesce(INVESTOR_FLOOD_FEE, 0) -
            Coalesce(INVESTOR_TAX_SERVICE_FEE, 0) - 
            Coalesce(INVESTOR_OTHER_FEE, 0)
    WHERE 
        INVESTOR_ID IN (Select i.INVESTOR_ID From inserted i)

END
GO

--
-- Sample data (zeros & nulls)
--

INSERT INTO DBO.INVESTOR
(
    INVESTOR_PRIN_BAL_PURCHASED,
    INVESTOR_DISC_PREM_DOLLAR,
    INVESTOR_SRP_PREM_DOLLAR,
    INVESTOR_ADMIN_FEE,
    INVESTOR_WIRE_FEE,
    INVESTOR_FLOOD_FEE,
    INVESTOR_TAX_SERVICE_FEE,
    INVESTOR_OTHER_FEE
) 
VALUES 
(0, 0, 0, 0, 0, 0, 0, 0),
(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

-- Show the data
SELECT * FROM TEMPDB.DBO.INVESTOR
于 2013-09-10T14:10:25.193 に答える
0

次のように試してみてください。両方の問題が解決するはずです。

ALTER TRIGGER [dbo].[SelfCalFieldsTrigger] ON [dbo].[dynTable]
FOR INSERT, UPDATE AS
BEGIN

    UPDATE [dbo].dynTable
        SET INVESTOR_DISC_PREM_PERCENT = Coalesce(INVESTOR_DISC_PREM_DOLLAR, 0)/
                Coalesce(INVESTOR_PRIN_BAL_PURCHASED, 0)*100,
            INVESTOR_SRP = Coalesce(INVESTOR_SRP_PREM_DOLLAR, 0)/
                Coalesce(INVESTOR_PRIN_BAL_PURCHASED, 0)*100,
            PURCHASE_WIRE_AMOUNT = Coalesce(INVESTOR_PRIN_BAL_PURCHASED, 0)-
                Coalesce(INVESTOR_ADMIN_FEE, 0)-
                Coalesce(INVESTOR_WIRE_FEE, 0)- Coalesce(INVESTOR_FLOOD_FEE, 0)-
                Coalesce(INVESTOR_TAX_SERVICE_FEE, 0) - Coalesce(INVESTOR_OTHER_FEE, 0)
    WHERE Account_id IN(Select i.Account_id From inserted i)

END
于 2013-09-10T14:23:30.067 に答える