這更多的建議請求比問題。2存儲過程或使用合併語句
要從c#中插入/更新SQL服務器中的記錄,你會寫2個存儲過程。其中用於插入使用,將根據傳入的(這將是null或ID插入或更新記錄SQL合併陳述的紀錄,另一個用於更新記錄
或
寫1存儲過程0,如果它是新記錄)?
什麼是最好的標準?
我正在使用SQL Server 2008和C#4.0。
在此先感謝
這更多的建議請求比問題。2存儲過程或使用合併語句
要從c#中插入/更新SQL服務器中的記錄,你會寫2個存儲過程。其中用於插入使用,將根據傳入的(這將是null或ID插入或更新記錄SQL合併陳述的紀錄,另一個用於更新記錄
或
寫1存儲過程0,如果它是新記錄)?
什麼是最好的標準?
我正在使用SQL Server 2008和C#4.0。
在此先感謝
這是一個相當廣泛的問題,但根據您的業務邏輯肯定有一些可以說。
不是專注於存儲過程的內部,而是想想像這樣的問題:我是否希望存儲過程爲插入/更新指定邏輯,還是我希望應用程序能夠?
讓我們舉一個使用用戶數據的例子。用戶登錄到網站,並且您需要保存一些關於它們的信息。用戶保證有一個唯一的電子郵件地址,因爲這是您設置應用程序端業務邏輯的方式。
您可以將電子郵件地址以及其他用戶信息傳遞到存儲過程。然後,SP可以決定如何保存它。如果電子郵件不在表格中,它將執行插入操作。如果是,它會進行更新。這可以通過merge語句或if語句來完成。
比更重要的是如何這樣做,是確保你將數據庫ID保留在數據庫中。做不是把它們帶到應用層,除非絕對需要。數據庫ID是表格相互引用而不重複數據字段的一種方式。 (谷歌的「一般形式」的一些信息。)他們應該絕對沒有必要在你的應用層。
無論您使用何種數據,您都應該能夠找到一個唯一的屬性或一組屬性,它們將允許您構建一個可以處理插入或更新的單個存儲過程。
P.S.我目前遇到了問題來了,在其中,你會想要兩個存儲的特效場景,但如果我可以,我會更新這個答案...
UPDATE
假設我們已經有了列出用戶,其中用戶如下。
class User
int id;
string name;
string email;
您從某處獲得姓名和電子郵件,但您沒有ID。將用戶插入用戶列表時,增加一些整數並將新用戶的ID分配給該號碼。然後,將該數字傳遞到將執行合併或插入/更新的存儲過程中。這樣,你永遠不會傳入一個空的id到存儲過程中。
爲了不使數據庫透視更容易混淆,請命名保存此值「application_id」的列。 如果您需要在數據庫表中有一個單獨的自動遞增的ID,您也可以添加該ID。
這是相當主觀的,但我更喜歡創建一個存儲過程。嘗試更新;如果沒有行受到影響,請使用插入。
或者,在SQL 2005或更新版本上,可以使用MERGE
來簡化事情。
http://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx
感謝您的建議。 – Sun
當我發送 收集數據(數據表),這可能 包含新數據或更新現有的數值數據的,我會用合併。 否則對於單個插入和更新我會 使用單獨的存儲過程。對於單個插入和更新 ,您還可以使用單個存儲過程 - 如果主鍵值 不存在 - 請創建該記錄。如果存在 - 更新記錄。
更好的方法(避免查找)是更新行,如果rowcount爲0,則插入。 –
@AaronBertrand對於如何避免查找/掃描,我有點困惑。 UPDATE語句不一定要掃描表或索引來嘗試操作嗎? –
是的,但如果你首先說'IF EXISTS(SELECT * FROM table WHERE key = @key)',然後說'(UPDATE table SET val = @val WHERE key = @key)',你做了兩個操作,而不是一個(只有後者是必要的;結果告訴你前者會告訴你的同樣的事情)。如果它最終成爲一個插入,無論你做了兩個搜索。我應該說「*潛在*避免尋求」 - 這一切都取決於更新與插入的比率,它有多好。 –
當你說「從C#」你的意思是ADO.NET或SQL CLR程序集? –
它使用ADO.Net – Sun
我喜歡他們提供的小工作單元。這樣,不同的技術可以毫不含糊地恰當地使用它們。 – Josh