私のテーブルにはこれらの値が含まれています
Name VARCHAR(50),
Program VARCHAR(50),
Branch VARCHAR(30),
TotalP INT,
TotalN INT)
名前がまだ存在しない場合、このテーブルにレコードを挿入しようとしました。これはおそらくここですでに回答されていますが、検索に何かを入力すると、7000以上の結果が表示され、100以上を調べてもまだ答えが見つかりません. ありとあらゆる助けをいただければ幸いです。
私のテーブルにはこれらの値が含まれています
Name VARCHAR(50),
Program VARCHAR(50),
Branch VARCHAR(30),
TotalP INT,
TotalN INT)
名前がまだ存在しない場合、このテーブルにレコードを挿入しようとしました。これはおそらくここですでに回答されていますが、検索に何かを入力すると、7000以上の結果が表示され、100以上を調べてもまだ答えが見つかりません. ありとあらゆる助けをいただければ幸いです。
並行性について心配していない場合は、次のように動作します。
IF NOT EXISTS (
SELECT 1
FROM YourTable
WHERE Name = @Name
)
BEGIN
INSERT INTO YourTable (Name, Program, Branch, TotalP, TotalN)
VALUES (@Name, @Program, @Branch, @TotalP, @TotalN)
END
ここでの問題は、2 つのプロセスが同時に同じものを追加しようとするとname
...両方ともIF NOT EXISTS
チェックに合格し、両方ともINSERT
.
これを防ぐにname
は、挿入の 1 つが失敗する列に一意の制約を追加するか、または をNOT EXISTS
使用してチェックでテーブルをロックすることができますWITH (UPDLOCK, HOLDLOCK)
。これにより、同時実行性は低下しますが、エラーは発生しません。
編集:
必要な値がSELECT
ステートメントからのものである場合、次のように動作します。
INSERT INTO YourDestinationTable (Name, Program, Branch, TotalP, TotalN)
SELECT st.Name, st.Program, st.Branch, st.TotalP, st.TotalN
FROM
YourSourceTable st
LEFT JOIN YourDestinationTable dt
ON dt.Name = st.Name
WHERE
dt.Name IS NULL
-- Add in any other conditions for YourSourceTable here...
YourSourceTable
これは、行が見つからない場合に行を挿入します ... andチェックYourDestinationTable
を使用して実装されます。LEFT JOIN
IS NULL
これには以前と同じ注意事項があります... 2 つのプロセスがこのステートメントを同時に実行すると、name
値が重複する可能性があります。に一意の制約を追加するか、トランザクション内に存在するかどうかをテストしている宛先テーブルの行で をname
実行します。(UPDLOCK, HOLDLOCK)
BEGIN TRANSACTION
IF NOT EXISTS (
SELECT 1
FROM
YourSourceTable st
JOIN YourDestinationTable dt WITH (UPDLOCK, HOLDLOCK)
ON dt.Name = st.Name
-- WHERE
-- Add in any other conditions for YourSourceTable here...
)
BEGIN
INSERT INTO YourDestinationTable (Name, Program, Branch, TotalP, TotalN)
SELECT Name, Program, Branch, TotalP, TotalN
FROM YourSourceTable st
-- WHERE
-- Add in any other conditions for YourSourceTable here...
END
COMMIT