2

これが私が持っている2つのテーブルです。顧客が1つの銀行から5つ以上の口座を持つことはできませんが、合計で5つ以上持つことができるというトリガーを実装したいと考えています。

  CREATE TABLE ACCOUNT(
   ACCOUNT_NO VARCHAR(20) NOT NULL,
   BALANCE REAL,
   BANK_CODE VARCHAR(20),
   BRANCH_NO VARCHAR(25),
   ACCOUNT_CODE VARCHAR(20),
   PRIMARY KEY(ACCOUNT_NO),
 );

 CREATE TABLE ACCOUNT_CUSTOMER(
   CUS_NO VARCHAR(20) NOT NULL,
   ACCOUNT_NO VARCHAR(20) NOT NULL,

   PRIMARY KEY(CUS_NO,ACCOUNT_NO),
       FOREIGN KEY(ACCOUNT_NO) REFERENCES ACCOUNT(ACCOUNT_NO),
   );

heres は私が書いたトリガーですが、単一の銀行ではなくすべての銀行のすべての口座をチェックするため、合計で 5 つを超える口座を作成することはできません。

    CREATE TRIGGER TRIGGER1
    ON ACCOUNT_CUSTOMER 
    FOR INSERT,UPDATE
    AS BEGIN
    DECLARE @COUNT INT
    DECLARE @CUS_NO VARCHAR(20)

    SELECT @COUNT=COUNT(AC.ACCOUNT_NO)
    FROM INSERTED I,ACCOUNT_CUSTOMER AC
    WHERE I.CUS_NO=AC.CUS_NO
    GROUP BY(AC.CUS_NO)

    IF @COUNT>5
    ROLLBACK TRANSACTION
    END

私が推測するように、問題はGROUPBY関数内にあります。

4

5 に答える 5

3

これは、制約を使用して簡単に実装できます。

CREATE TABLE ACCOUNT(
   ACCOUNT_NO VARCHAR(20) NOT NULL,
   BALANCE REAL,
   BANK_CODE VARCHAR(20),
   BRANCH_NO VARCHAR(25),
   ACCOUNT_CODE VARCHAR(20),
   PRIMARY KEY(ACCOUNT_NO),
   UNIQUE(ACCOUNT_NO,BANK_CODE)
 );

 CREATE TABLE ACCOUNT_CUSTOMER(
   CUS_NO VARCHAR(20) NOT NULL,
   ACCOUNT_NO VARCHAR(20) NOT NULL,
       BANK_CODE VARCHAR(20),
   NUMBER_FOR_BANK INT NOT NULL CHECK(NUMBER_FOR_BANK BETWEEN 1 AND 5),      
   PRIMARY KEY(CUS_NO,ACCOUNT_NO),
   UNIQUE(CUS_NO,BANK_CODE,NUMBER_FOR_BANK),
       FOREIGN KEY(ACCOUNT_NO, BANK_CODE) REFERENCES ACCOUNT(ACCOUNT_NO, BANK_CODE),
   );

編集: トリガーが起動しないことがあります。信頼できる制約のみが、データの整合性を 100% 保証します。

挿入するには、Numbers テーブルを使用します。

INSERT INTO ACCOUNT_CUSTOMER(
   CUS_NO,
   ACCOUNT_NO,
       BANK_CODE,
   NUMBER_FOR_BANK
   )
SELECT TOP 1    @CUS_NO,
   @ACCOUNT_NO,
       @BANK_CODE,
   NUMBER
FROM dbo.Numbers WHERE NUMBER BETWEEN 1 AND 5
AND NOT EXISTS(SELECT * FROM ACCOUNT_CUSTOMER WHERE CUS_NO=@CUS_NO AND BANK_CODE=@BANK_CODE)

BANK_CODE の変更を禁止するトリガーを使用します。

于 2010-09-16T15:58:10.957 に答える
1

私はこのようなことを試してみます:

トリガーのこの部分を交換してください

SELECT @COUNT=COUNT(AC.ACCOUNT_NO)
FROM INSERTED I,ACCOUNT_CUSTOMER AC
WHERE I.CUS_NO=AC.CUS_NO
GROUP BY(AC.CUS_NO)

IF @COUNT>5
ROLLBACK TRANSACTION

これとともに:

IF EXISTS (
        SELECT COUNT(a.ACCOUNT_NO)
        FROM INSERTED i
                JOIN ACCOUNT a ON i.ACCOUNT_NO = a.ACCOUNT_NO
                JOIN ACCOUNT_CUSTOMER c ON i.CUS_NO = c.CUS_NO
        GROUP BY c.CUS_NO, a.BANK_CODE
        HAVING COUNT(a.ACCOUNT_NO) >= 5
    )
    ROLLBACK TRANSACTION

また、INSERTED テーブルには複数のレコードが含まれる可能性があることも考慮してください。これらのレコードが複数の顧客のものであり、いずれかの顧客がこのトリガーによってトランザクションがロールバックされる場合、ルールに違反していない顧客の更新は適用されません。これは発生しない可能性があります (アプリケーションが一度に複数の顧客のレコードを更新しない場合)、または意図した動作である可能性があります。

于 2010-09-16T16:28:20.960 に答える
0

答えてくれてありがとう、すべてを調べた後、この解決策を思いつきました。ネストされたクエリを挿入して、銀行コードを取得し、そのコードによってカウントを取得します

CREATE TRIGGER TRIGGER1
ON ACCOUNT_CUSTOMER 
FOR INSERT,UPDATE
AS BEGIN
DECLARE @COUNT INT
DECLARE @CUS_NO VARCHAR(20)

SELECT @COUNT=COUNT(*)
FROM ACCOUNT_CUSTOMER AC, ACCOUNT A
WHERE A.ACCOUNT_NO=AC.ACCOUNT_NO AND A.BANK_CODE=
               (SELECT A.BANK_CODE 
                FROM DIT09C_0293_ACCOUNT A, INSERTED I
                WHERE A.ACCOUNT_NO=I.ACCOUNT_NO
                )
    IF @COUNT>5
        ROLLBACK TRANSACTION
END
于 2010-09-17T03:39:34.137 に答える
0

トリガーの現在のクエリの代わりにこれを試してください。これはうまくいくかもしれないと思います。

私の構文は少しずれているかもしれませんが、一般的な考え方はわかります。

SELECT @COUNT=MAX(COUNT(AC.ACCOUNT_NO))
FROM INSERTED I 
INNER JOIN ACCOUNT_CUSTOMER AC ON I.CUS_NO=AC.CUS_NO 
INNER JOIN ACCOUNT A ON AC.ACCOUNT_NO = A.ACCOUNT_NO
GROUP BY(AC.CUS_NO, A.BANK_CODE) 
于 2010-09-16T14:47:13.360 に答える
0

クエリの問題は、一意の顧客 ID でのみ検索していることです。

クエリでは、一意の顧客 ID と銀行 ID を一緒に検索する必要があります。正確なクエリはあなたに任せますが、疑似コードで必要なものは次のとおりです。

SELECT COUNT(customer_id)
FROM table_name
WHERE customer_id = customer_id_to_validate
AND bank_id = bank_id_to_validate

これは、顧客と銀行の組み合わせが何回存在するかを返します。それがあなたが望む限界です。

于 2010-09-16T14:47:37.710 に答える