2016-05-05 16 views
1

これはわかりやすい例です。このようになります請負人という名前のテーブルがあると想定しますビューを使用したSQL Serverの挿入

name | paid_adjustment_amount | adj_date 
Bob | 1000     | 4/7/2016 
Mary | 2000     | 4/8/2016 
Bill | 5000     | 4/8/2016 
Mary | 4000     | 4/10/2016 
Bill | (1000)     | 4/12/2016 
Ann | 3000     | 4/30/2016 

請負テーブルのビューがありますが、それは名前でグループ化されたpaid_adustment_amountの単なる和である、のは、それをv_sum呼びましょう。だから、次のようになります。

name | total_paid_amount 
Bob | 1000 
Mary | 6000 
Bill | 4000 
Ann | 3000 

最後に、このようになりますto_date_paymentと呼ばれる別のテーブルがあります:私はv_sumビューにto_date_paymentテーブルの情報を比較し、挿入したい

name | paid_to_date_amount 
Bob | 1000 
Mary | 8000 
Bill | 3000 
Ann | 3000 
Joe | 4000  

は、コントローラーテーブルの新しい行が調整を示します。このようなもの:

INSERT INTO contractor 
SELECT to_date_payment.name, 
    to_date_payment.paid_to_date_amount - v_sum.total_paid_amount, 
    GETDATE() 
FROM to_date_payment 
LEFT JOIN v_sum ON to_date_payment.name = v_sum.name 
WHERE to_date_payment.paid_to_date_amount - v_sum.total_paid_amount <> 0 
    OR v_sum.name IS NULL 

ビューを使用する際に問題がありますか?私の理解は、私が間違っている場合は私を修正してください、そのビューはクエリの結果セットです。そして、ビューは私が新​​しいレコードを挿入しているテーブルのものなので、データの整合性に問題があるかもしれません。

ありがとうございました!

答えて

0

あなたがしていることを十分に理解するためには、v_sumの定義も提供する必要があります。一般に、ビューは、特に索引付けされるときに、いくつかの利点を提供することがあります。詳細はherehereです。

ビューの単純な使用は、パフォーマンス上の利点はありませんが、テーブルに対して抽象化を提供するのに非常に適しています。

あなたの特定のケースでは、私は、ビューに参加することに何の問題が表示されていないが、私はに関連する潜在的な問題を心配します:

1)VARCHARの代わりの整数を使用して登録しよう - to_date_payment.name ON = v_sum.name - 可能であれば、整数(IDまたは外部キーID)の値がJOINになるようにしてください(整数列に適用されるインデックスは小さなキーを持ち、比較は少し速い)。

2)またはクエリのORは、通常、パフォーマンスの問題を引き起こします。 - NULL NULLリターンを含むデフォルト、算術演算によって

SELECT to_date_payment.name, 
    to_date_payment.paid_to_date_amount - v_sum.total_paid_amount, 
    GETDATE() 
FROM to_date_payment 
JOIN v_sum ON to_date_payment.name = v_sum.name 
WHERE to_date_payment.paid_to_date_amount - v_sum.total_paid_amount <> 0 

UNION ALL 

SELECT to_date_payment.name, 
    to_date_payment.paid_to_date_amount, -- or NULL if this is really intended 
    GETDATE() 
FROM to_date_payment 
-- NOT EXISTS is usually faster than LEFT JOIN ... IS NULL 
WHERE NOT EXISTS (SELECT 1 FROM v_sum V WHERE V.name = to_date_payment.name) 

3)可能な望ましくない結果:しようとする一つのことは、次のようにSELECTを変更することです。 v_sumに一致するものがない場合、v_sum.total_paid_amountはNULLで、to_date_payment.paid_to_date_amount - v_sum.total_paid_amountはNULLと評価されます。これは正しいです?たぶんto_date_payment.paid_to_date_amount - ISNULL(v_sum.total_paid_amount, 0)が意図されています。

+0

ありがとうございました! #1残念ながら私は一意の識別子を管理することはできません。これらは名前ではありませんが、VARCHARを必要とする外部ソースから提供される英数字の組み合わせ(AB123など)です。 #2私はORの代わりにUNIONを使用しています。しかし、私はすべてのORとINを避けるべきですか?私はIN句に6つの項目を持つ基準を持っている無関係のクエリを考えることができます。代わりに5つの組合で6つのクエリを書くべきですか? #3良いキャッチ。私は助けに感謝します! – dwarn

+0

#2。これは、実際の実行計画に基づいて検討する必要があります。非常に多数のレコードがない場合でも、OR/INはまだ妥当な時間を得ることができます。また、複雑な照会の場合、一時表を定義していくつかの挿入を実行することができます。可能性のあるパフォーマンスの最適化の他に、簡単なデバッグも可能です(各挿入後に一時的にチェックします)。 – Alexei

関連する問題