0

テーブルからカウントを取得し、次のように別のテーブルに追加する、挿入が簡単なトリガーを作成しようとしています。

CREATE TABLE [poll-count](
id VARCHAR(100),
altid BIGINT,
option_order BIGINT,
uip VARCHAR(50),
[uid] VARCHAR(100),
[order] BIGINT
PRIMARY KEY NONCLUSTERED([order]),
FOREIGN KEY ([order]) references ord ([order]  
)
GO

CREATE TRIGGER [get-poll-count]
ON [poll-count]
FOR INSERT 
AS 
    BEGIN
        DECLARE @count INT
        SET @count = (SELECT COUNT (*) FROM [poll-count] WHERE option_order = i.option_order)
        UPDATE [poll-options] SET [total] = @count WHERE [order] = i.option_order
    END
GO

これを実行しようとすると、次のエラーが発生します。

マルチパート識別子「i.option_order」をバインドできませんでした

何が問題ですか?

ありがとう

4

1 に答える 1

3

現在、トリガーは常に1行の挿入があることを前提としています。このようなものでトリガーを試しましたか?

INSERT dbo.[poll-options](option_order --, ...)
  VALUES(1 --, ...),
        (2 --, ...);

また、SQL Serverは「挿入されたテーブルにアクセスできない」と言いますが、ステートメントはこれを示しています。どこを参照しますかinserted(これが有効なサブクエリ構造であったとしても)?

SET @count = (SELECT COUNT (*) FROM [poll-count] 
  WHERE option_order = i.option_order)
-----------------------^ "i" <> "inserted"

insertedこれは、複数行の挿入を適切に参照し、適切に処理するトリガーです。

CREATE TRIGGER dbo.pollupdate
ON dbo.[poll-options]
FOR INSERT
AS
BEGIN
    SET NOCOUNT ON;

    ;WITH x AS 
    (
      SELECT option_order, c = COUNT(*)
       FROM dbo.[poll-options] AS p
       WHERE EXISTS 
       (
        SELECT 1 FROM inserted 
        WHERE option_order = p.option_order
       )
       GROUP BY option_order
    )
    UPDATE p SET total = x.c
      FROM dbo.[poll-options] AS p
      INNER JOIN x 
      ON p.option_order = x.option_order;
END
GO

しかし、なぜこのデータをすべての行に保存したいのですか?実行時にいつでもカウントを導き出し、それが完全に最新であることを認識し、トリガーの必要性を完全に回避することができます。実行時にカウントを導出するパフォーマンスの側面に関する場合、DML中にほぼ同じメンテナンスコストでこの先行書き込み最適化を実装するはるかに簡単な方法は、インデックス付きビューを作成することです。

CREATE VIEW dbo.[poll-options-count]
WITH SCHEMABINDING
AS
  SELECT option_order, c = COUNT_BIG(*)
    FROM dbo.[poll-options]
    GROUP BY option_order;
GO
CREATE UNIQUE CLUSTERED INDEX oo ON dbo.[poll-options-count](option_order);
GO

これでインデックスが維持され、任意の(またはすべての)option_order値の非常に迅速なカウントを導き出すことができます。もちろん、クエリ時間の改善がメンテナンスを増やす価値があるかどうかをテストします(ただし、特定の挿入でさらに多くの行に影響を与える可能性があることを除いて、トリガーでその価格をすでに支払っています...) 。

-最後の提案として、オブジェクト名のように特殊文字を使用しないでください。それはあなたに常にそれを包むことを強制するだけで[square brackets]あり、それは誰にとっても楽しいことではありません。

于 2013-01-20T00:28:06.573 に答える