これは機能しますが、冗長性を削除したいと思います。 varsを使用する必要がないように、更新を単一のselectステートメントとマージする方法はありますか?
DECLARE
@OrgAddress1 varchar,
@OrgAddress2 varchar,
@OrgCity varchar,
@OrgState varchar,
@OrgZip varchar,
@DestAddress1 varchar,
@DestAddress2 varchar,
@DestCity varchar,
@DestState varchar,
@DestZip varchar
SELECT
@OrgAddress1 = OrgAddress,
@OrgAddress2 = OrgAddress2,
@OrgCity = OrgCity,
@OrgState = OrgState,
@OrgZip = OrgZip,
@DestAddress1 = DestAddress,
@DestAddress2 = DestAddress2,
@DestCity = DestCity,
@DestState = DestState,
@DestZip = DestZip
FROM
ProfilerTest.dbo.BookingDetails
WHERE
MyID=@MyID
UPDATE SHIPMENT
SET
OrgAddress1 = @OrgAddress1,
OrgAddress2 = @OrgAddress2,
OrgCity = @OrgCity,
OrgState = @OrgState,
OrgZip = @OrgZip,
DestAddress1 = @DestAddress1,
DestAddress2 = @DestAddress2,
DestCity = @DestCity,
DestState = @DestState,
DestZip = @DestZip
WHERE
MyID2=@ MyID2
このような何かが動作するはずです(今はテストできません-メモリから):
UPDATE SHIPMENT
SET
OrgAddress1 = BD.OrgAddress1,
OrgAddress2 = BD.OrgAddress2,
OrgCity = BD.OrgCity,
OrgState = BD.OrgState,
OrgZip = BD.OrgZip,
DestAddress1 = BD.DestAddress1,
DestAddress2 = BD.DestAddress2,
DestCity = BD.DestCity,
DestState = BD.DestState,
DestZip = BD.DestZip
FROM
BookingDetails BD
WHERE
SHIPMENT.MyID2 = @MyID2
AND
BD.MyID = @MyID
それは役立ちますか?
あなたは次の線に沿って何かをすることができるはずです
UPDATE s
SET
OrgAddress1 = bd.OrgAddress1,
OrgAddress2 = bd.OrgAddress2,
...
DestZip = bd.DestZip
FROM
Shipment s, ProfilerTest.dbo.BookingDetails bd
WHERE
bd.MyID = @MyId AND s.MyID2 = @MyID2
FROMステートメントは(より具体的な結合を使用して)より最適化することができますが、上記の方法でうまくいくはずです。また、この方法で作成すると、UPDATEの変更のプレビューを見ることができますUPDATE s SET
を読むSELECT
!更新が行われた場合に表示されるデータが表示されます。
次を使用できます。
UPDATE s SET
s.Field1 = q.Field1,
s.Field2 = q.Field2,
(list of fields...)
FROM (
SELECT Field1, Field2, (list of fields...)
FROM ProfilerTest.dbo.BookingDetails
WHERE MyID=@MyID
) q
WHERE s.MyID2=@ MyID2
更新を使用できます...
何かのようなもの:
出荷セットの更新...出荷内部結合からProfilerTest.dbo.BookingDetailsの...
シーケンス番号を追加した同様の問題を解決する必要がありました(そのため、親IDでグループ化されたアイテムには、順序を変更できるシーケンスがあります(おそらく、ユーザーは順序を変更して順序を変更できます)。
私の場合、それは患者の保険であり、ユーザーは割り当てられた順序を設定できるので、主キーを使用するだけでは長期的には役に立ちませんが、デフォルトを設定するのには便利です。
他のすべてのソリューションの問題は、特定の集計関数がSELECTの外部で許可されないことです
このSELECTは、新しいシーケンス番号を取得します。
select PatientID,
PatientInsuranceID,
Sequence,
Row_Number() over(partition by PatientID order by PatientInsuranceID) as RowNum
from PatientInsurance
order by PatientID, PatientInsuranceID
この更新コマンドは簡単ですが、許可されていません:
update PatientInsurance
set Sequence = Row_Number() over(partition by PatientID order by PatientInsuranceID)
解決したソリューション(私はちょうどそれをやった)、eKek0のソリューションに似ています:
UPDATE PatientInsurance
SET PatientInsurance.Sequence = q.RowNum
FROM (select PatientInsuranceID,
Row_Number() over(partition by PatientID order by PatientInsuranceID) as RowNum
from PatientInsurance
) as q
WHERE PatientInsurance.PatientInsuranceID=q.PatientInsuranceID
これにより、一致させる必要があるIDと、そのIDに設定する必要がある値を選択できます。 SELECTの外では動作しないRow_Number()を使用していなかった場合、他のソリューションは問題なかったでしょう。
これが1回の操作であることを考えると、コーディングはまだ単純であり、実行速度は4000行以上に対して十分に高速です。
このように書きます
UPDATE s
SET OrgAddress1 = bd.OrgAddress1, OrgAddress2 = bd.OrgAddress2,
... DestZip = bd.DestZip
--select s.OrgAddress1, bd.OrgAddress1, s.OrgAddress2, bd.OrgAddress2, etc
FROM Shipment s
JOIN ProfilerTest.dbo.BookingDetails bd on bd.MyID =s.MyID2
WHERE bd.MyID = @MyId
暗黙的な結合は悪いことなので、この方法は明示的です。コメントアウトしたselect(通常は、古い値と新しい値を更新するフィールドを並べて指定します)を実行して、更新しようとしているものが正確に更新することを確認できます。