2009-08-10 23 views
2

在過去幾個月中,我已經運行了多種情況,其中傳統SQL SP正在返回主要由冗餘信息組成的單個表。SQL Server 2005 - 是否有任何重大的負面影響返回多個表w /存儲過程?

例子:

選擇客戶ID,CustomerEmail,CustomerAddress,InventoryLineItem,ShipQty從...

返回:

55 [email protected] 723 StreetName InvLineItem#1 45 
55 [email protected] 723 StreetName InvLineItem#2 42 
55 [email protected] 723 StreetName InvLineItem#3 1 
55 [email protected] 723 StreetName InvLineItem#4 5 
55 [email protected] 723 StreetName InvLineItem#5 200 
55 [email protected] 723 StreetName InvLineItem#6 7045 

(前三個字段,永不改變)

因爲我作爲項目中唯一的開發人員,我已經開始將其分解爲兩個選擇語句。 (I在接收.NET代碼以及工作)

選擇客戶ID,CustomerEmail,CustomerAddress從....

Returns: 55 [email protected] 723 Streetname <-- 1 record 

選擇InventoryLineItem,ShipQty從.... 返回:

LineItem#1 45 
LineItem#2 42 
LineItem#3 1 

顯然在.NET中得到的數據集是較小的,但它真的讓我有時在select語句中有10個字段是alwa在所有情況下都完全一樣。有些查詢甚至可能會返回數十條記錄。

我覺得我在這裏做了正確的事情,但我還是那句話我沒有SQL親。

我有什麼理由避免這種做法嗎?

提前感謝您的時間。

回答

3

如果您的客戶端使用從存儲過程返回的數據可以正確處理多個結果集,那麼不會,絕對沒有理由不使用它們。

他們有幾個優勢,因爲你已經指出自己:
- 減少數據轉移 量 - 爲您節省往返的服務器相比,有 - 保持常態化,數據沒有不必要的重複打電話給兩個單獨的存儲過程(一個用於標題,一個用於詳細數據)

所以總而言之 - 去吧! :-)對我來說似乎是一個好主意。

馬克

3

好了,我在這裏大的回答是,如果你餵養輸出到一個報告框架,如SSRS,多個表將會讓您的生活困難 - 報告框架是相當不錯的,在服用非規範化的結果並處理它們成漂亮的報告。

至於性能也越高,不,你沒有理由,以避免多個結果脫落的存儲過程。只要你在客戶端使用DataReader和.NextResult(),IMO就是最好的選擇。

2

我認爲你對冗餘數據的想法是正確的。
這是額外的數據流經網絡。

這是可能的,你可能會打電話與您選擇相同參數的一個存儲過程。

例如GetCustomerOrders 'ALFKI' - 這可能是返回

ALFKI | ALFA客戶| OID001 ......
ALFKI | ALFA客戶| OID002 ......
ALFKI | ALFA客戶| OID003 ......

所以,你可以避開你所傳遞的參數傳遞給存儲過程域的選擇。

編輯:第二個想法,可能有另一個存儲過程 - 這將返回客戶相關的信息。發票相關程序將返回給定客戶ID的發票數據。

+0

包括你在你的回報集合傳遞的參數意味着應用程序已被遺忘時,它提交的查詢和之間的值時,它得到的數據傳回。 – 2009-08-10 13:53:48

1

我發現存儲過程返回的內容的一致性可能非常重要,但您肯定會看到沒有一致性的系統存儲過程(請考慮sp_help)。

因此,這取決於您的操作,以及您的客戶端代碼是否能夠處理它。任何時候你想要提前綁定,或者你有一個客戶端會詢問存儲過程將返回什麼(比如任何報告客戶端,或者LINQ等ORM系統),那麼你可能會遇到麻煩。如果你使用.Net代碼,並且你期望每次都看到不同的結果集結構,那麼這可能不是什麼大不了的事。

在一天結束時,如果您在某些情況下有許多列可能爲空,這可能會給您的客戶帶來更大的靈活性,但這完全取決於您希望將作品放在哪裏。

我個人的偏好是有一個總是相同形狀的結果集。但是,我也會考慮把它放在一個表值函數中,這樣我可以更靈活地處理結果(比如分組等)。我發現存儲過程對於客戶端需要調用某些內容時非常有用,但如果我想要以不同方式處理其他內容,我寧願有一個視圖或一個表值函數來生成它(很像從系統中移出存儲過程給微軟停下來的DMVs)。

Rob

3

我一直使用多個結果集。

在你的情況,我會有2,一個頭和一個細節。 通常,客戶端無論如何都必須提取標題:當客戶端不能像這樣使用它時,爲什麼我應該將其扁平化(例如膨脹)?

我使用它的其他領域是網頁。對數據庫的每次調用都有足夠的數據用於一個動作或在屏幕上彈出(現在不假設緩存)。

假設一個標題行5爲詳細信息行的詳細信息行+下拉列表。

另一個原因是性能。 SQL查詢可以調整,C#代碼可以調整,但往返(例如web < - >數據庫)不能。

1

我有這樣做最大的擔心是,如果你的數據庫是高事務的兩個查詢之間的數據可能不正確有關。換句話說,第二個查詢可能包含未在第一查詢記錄(因爲它們要加入,就像第一個查詢已完成),所以你不知道從他們的相關數據。當然,在第二個查詢運行之前,第一個查詢的記錄被刪除,這當然也可以反向工作。

+0

優秀點。 – 2009-08-10 21:14:14

+0

這東西可以(也應該)與事務隔離處理;的SP往往由多個語句,以使這種一致性的說法是不是真的取決於是否正在返回的一個或多個記錄集。 – Lucero 2011-05-14 11:13:25

1

聽起來好像這並不適用於您的情況,但如果存儲過程被另一個存儲過程調用,任何數據集後,第一個返回值將是「看不見」 - 也就是說,不能訪問 - 通過調用程序。使得難以執行INSERT ... EXECUTE ...語句。 (這些設置將返回到調用應用程序,當然)。