2014-01-28 79 views
1

我知道這可能是一個不好的例子,但在這種情況下,我的問題更多的是處理StringBuilder而不是我的SQL查詢的最好/最有效的方法本身,所以請多多包涵......通過遍歷列表創建新的StringBuilder,刪除最後一個元素

作爲一個例子來說明什麼,我希望獲得,假設我有一個數據庫表,所有這些都具有相同結構的大名單,並我想創建一個查詢來在一個查詢中從所有這些查詢中提取數據。

我想這樣做的方法是:

Dim MyTables As List(Of String) = {"Table1", "Table2", "Table3" ... "TableN"}.ToList 
    Dim SQLQuery As New StringBuilder 

    For Each tbl As String In MyTables 
     SQLQuery.AppendLine("SELECT [col1], [col2], [col3] FROM " & tbl) 
     SQLQuery.AppendLine("UNION") 
    Next 

同樣,無視這是否是要做到這一點(雖然我很想知道是否有更好的方法最好的方式,但我不不想讓答案朝這個方向傾斜 - 在這種情況下,我更有興趣知道如何有效地處理StringBuilder)。

鑑於我這樣做的方法,我的StringBuilder都將有一個額外的UNION & vbCrLf在它的結束,我需要刪除 - 我知道我可以使用的東西線沿線的做到這一點:

SQLQuery.Remove(SQLQuery.Length - ("UNION" & vbCrLf).Length, ("UNION" & vbCrLf).Length) 

當然,我可以提高效率,但我的問題基本上是什麼是最好/最有效的方式來創建這樣一個使用循環的「串聯器」,因此,這是一個相當大的字符串,如果你以我的方式做了,它會被追加到最後?

我知道這個問題是用VB編寫的,但我在C#中的答案同樣適用。謝謝!!!

+1

截斷只是'SQLQuery.Lenght - = 7;' – Steve

+1

我認爲你所做的已經相當有效。在stringbuilder末尾移除給定長度的元素是有效的,並且AFAIK獨立於stringlength - 另外它只在循環結束時執行一次。 – Marwie

回答

6

當你需要建立一個由您選擇的分隔字符串分隔集合的元素組成的字符串,你不需要直接使用StringBuilder。此外,你甚至不需要一個循環:您可以使用String.Join方法,它採用隔板和IEnumerable<T>,並返回一個由分離集合的元素組成的字符串您指定的任何分隔符:

// C# answer 
var query = string.Join(
    "\nUNION\n" 
, MyTables.Select(tbl => "SELECT [col1], [col2], [col3] FROM "+ tbl) 
); 

注意:除非你真的希望您的RDBMS消除重複項,請考慮使用UNION ALL運算符代替UNION。當行數很大時,這種變化對性能的影響可能很大。

+1

這個答案對我最有意義 - 我也非常喜歡Linq'.Select'。謝謝!! –

0

我建議將它追加到List<string>並最終加入它,但我不知道它會如何影響你的表現。

另一種方法是使用一個標誌,顯示您在第一次迭代中並在查詢之前追加UNION,而不是之後。

bool first = true; 

foreach (string tbl in MyTables) 
{ 
    if (first) 
     first = false; 
    else 
     SQLQuery.AppendLine(" UNION "); 

    SQLQuery.Append("SELECT [col1], [col2], [col3] FROM "); 
    SQLQuery.AppendLine(tbl); 
} 
0

那麼你可以在你的數據庫中只使用一個VIEW如果它支持它並且涉及的表總是相同的。

但隨着StringBuilder的辦法住,然後我會嘗試截斷長度只有

SQLQuery.Lenght -= 7 

OT(如果你想清楚)

SQLQuery.Lenght -= ("UNION"+ Environment.Newline).Length 

那麼我建議創建的StringBuilder估計容量。 例如,如果你的SELECT語句的平均長度的一種是300個字符,你有10個表,你可以開始創建的4000個字符

Dim SQLQuery = New StringBuilder(4000) 

內部容量的StringBuilder這將避免不斷返工放大內部緩衝區,同時添加新數據。

4

我會做這樣的事情,而不是:

Dim myTables = {"Table1", "Table2", "Table3" ... "TableN"} 
Dim queries = myTables.Select(Function(tbl) "SELECT [col1], [col2], [col3] FROM " & tbl) 

Return String.Join(vbNewLine & "UNION" & vbNewLine, queries) 

不管怎樣,SQL查詢會是怎樣發生的大部分時間。從串聯到string.join到StringBuilder的時間轉換的收益與查詢執行的時間相比毫無意義(認爲1ms vs 1000ms)。

+1

真的是一個很棒的解決方案!我希望我可以選擇2個答案,但是你發佈了** JUST **後dasblinkenlight誰建議完全相同的事情,但確實,**謝謝你太多了** –

相關問題