2009-11-04 53 views
0

我遇到了在刷新時插入重複項的問題。我們的團隊決定在sql中使用'if exists'是阻止重複插入的最好方法。但是,如果參數設置爲null會怎麼樣?如果存在使用

string cmdText = " if (not exists(select * from table where field1 = @field1 and field2 = @field2 and field3 = @field3)) Insert into table(field1,field2,field3) Values(@field1,@field2,@field3)"; 

if (txtfield1.text != "") 
    cmd.Parameters.Add(new SqlParameter("@field1", txtfield1.text)); 
else 
    cmd.Parameters.Add(new SqlParameter("@ field1", DBNull.Value)); 

    cmd.Parameters.Add(new SqlParameter("@field2", txtfield2)); 
    cmd.Parameters.Add(new SqlParameter("@field3", txtfield3)); 

當field1中存在空值時,這不起作用。

+1

如果你想避免重複,爲什麼不添加一個唯一的鍵約束到你的表? – 2009-11-04 15:35:10

+0

「關於刷新」 - 關於刷新什麼?一個網頁?在源代碼解決問題(請參閱http://stackoverflow.com/questions/481564/how-to-prevent-repeated-postbacks-from-confusing-my-business-layer等) – 2009-11-04 15:40:16

+0

使用表定義和約束對於這些東西。編寫代碼更少,工作速度更快。看到我的答案。 – Egon 2009-11-04 15:47:01

回答

8

你可以環繞ISNULL的什麼你的領域考慮到了空

isnull(field1, '') = isnull(@field1, '') and 
isnull(field2, '') = isnull(@field2, '') and 
isnull(field3, '') = isnull(@field, '') 
+0

這些類型的代碼解決方案存在問題。每次你寫一個sql查詢到這個表,你都必須使用這個測試。你可以用約束來做到這一點,它更乾淨,更容易。 – Egon 2009-11-04 15:52:21

+0

@egon這對於字段是正確的,我假定他們不會修改數據庫模式。但是,您仍然需要參數的邏輯。 – Joseph 2009-11-04 16:00:45

+0

@joseph你可以使用觸發器。如果他們不能修改架構,那麼你的解決方案就可以。但我仍然認爲這些檢查應該在數據庫中。 – Egon 2009-11-04 17:55:39

1

那麼你將不得不使用IS而不是=如果你打算將@field1設置爲NULL。 NULL不會與相等運算符一起使用。你需要使用一個等價類型'IS'。

 
string cmdText = " if (not exists(select * from table where field1 = @field1 and field2 = @field2 and field3 = @field3)) Insert into table(field1,field2,field3) Values(@field1,@field2,@field3)"; 

 
string cmdText = ""; 
if (txtfield1.text != "") 
cmdText = " if (not exists(select * from table where field1 = @field1 and field2 = @field2 and field3 = @field3)) Insert into table(field1,field2,field3) Values(@field1,@field2,@field3)"; 
else 
cmdText = " if (not exists(select * from table where field1 IS @field1 and field2 = @field2 and field3 = @field3)) Insert into table(field1,field2,field3) Values(@field1,@field2,@field3)"; 
end if 

沖洗和重複和重構:)

2
where field1 IS @field1 

無效語法

使用ISNULL()

所以:

string cmdText = " if (not exists(select * from table where isnull(field1, '') = isnull(@field1, '') ... 
2

如果你不想在你的表重複,也許你的表應該有一個主鍵或至少一個唯一的聚集索引你field1,field2和field3。

這樣,你可以試試插入並捕獲錯誤,如果該行已經存在。

3

減少數據庫上的負載並從源頭解決問題不是一個好主意嗎?

通常,當你有一個頁面處理自己的提交時,即表單動作屬性指向自己,所以當有人在發佈內容後點擊刷新時,POST數據仍然是「活的」,並且被髮回到頁面。

更好的方法是將數據提交給第二個對象,該對象處理插入操作,然後將其重定向回來,重定向清除POST數據,併爲自己節省大量不必要的查詢。

Just my 2c

+0

我會將此與消除表中的重複項一起使用並加以限制。 – JeffO 2009-11-04 16:21:46

2

以下情況將有所幫助。

FIELD1爲空或@字段1 =字段1

2

在字段定義,你可以使用NOT NULL約束,使空元素的不就能夠在那裏。

http://www.w3schools.com/SQl/sql_notnull.asp

並使用SQL唯一約束,使他們必須是唯一的。

http://www.w3schools.com/SQl/sql_unique.asp

CREATE TABLE YourTable 
(
    Field1 varchar(255), 
    Field2 varchar(255), 
    Field3 varchar(255), 
    CONSTRAINT uc_fields UNIQUE (Field1, Field2, Field3) 
) 

CREATE TRIGGER table_null_convert 
    ON YourTable 
    FOR INSERT, UPDATE 
    REFERENCING NEW ROW AS n 
    FOR EACH ROW 
    SET n.Field1 = ISNULL(n.Field1, '') 
    SET n.Field2 = ISNULL(n.Field2, '') 
    SET n.Field3 = ISNULL(n.Field3, ''); 

你會被允許插入,如果這些條件得到滿足。

希望我得到了正確的觸發器。 :)

+0

如果用戶不知道其中一個值,用戶輸入什麼內容?聽起來像這些價值觀並不是他們的商業規則所要求的。 – JeffO 2009-11-04 16:19:10

+0

對不起,我誤解了。我以爲他們根本不需要NULL-s。我想我仍然會使用觸發器。 (不知道我是否完全正確觸發了觸發器,有一段時間沒有觸發器)。 – Egon 2009-11-04 17:54:02