2011-10-29 76 views
1

如何正確設置此代碼?我對這段代碼不滿意,我迷路了。用代碼隱藏條件構建查詢的最佳方法?

我給你一個簡單的例子,但查詢更復雜。

在此先感謝。

string aValue; 
string queryA; 
string queryB; 
string finalQuery; 

string queryA = @"SELECT column1 FROM table1 WHERE column1="; 
queryA += aValue; 

string queryB = @"SELECT column1, column2," 

if (aValue == "all"){ 
    queryB += @"column3"; 
} 
queryB += @"FROM table1 WHERE column1="; 
queryB += @"'" +aValue+ "'"; 

private void exportExcel(){ 

    // change the value with a dropdownlist 
    if (ddlType.selectedIndex(1)) 
      aValue = "typeA"; 
    else if(ddlType.selectedIndex(2)) 
      aValue = "typeB"; 
    else 
     aValue = "all"; 

    // select the query 
    if (aValue == "typeA") 
     finalQuery = queryA; 
    else if (aValue == "typeB") 
     finalQuery = queryB; 

    ExecQUery(finalQuery); 
} 

回答

3

在Java和C#(和幾乎其他任何平臺),你一定要包括直接在SQL中的值。這爲SQL注入攻擊開闢了道路,也使處理日期,時間和數字的格式變得棘手。

相反,您應該使用參數化的 SQL,指定參數中的值。 Java和C#之間的差異如何,但原理是一樣的。

這兩種平臺上的另一種方法是使用某種描述的ORM,而不是手動構建查詢。例如,在.NET中,您可能想要使用某種描述的LINQ提供程序,而在Java中,您可能需要使用類似Hibernate的東西。無論哪種方式,您都可以在更高的抽象級別上表達您的查詢,而不僅僅是原始SQL。

如果不知道你真正使用的是什麼平臺(或數據庫)並且沒有真正的查詢來查看,很難給出更具體的建議。

+0

是我使用 「SQL參數」 和我們沒有ORM。我需要格式化代碼的建議,也許可以使用其他函數來構建查詢 – TimeIsNear

+0

@ user359706:那麼,爲什麼要給出一個使用已知不良習慣的示例?你說「我們沒有ORM」,但是爲什麼*你不使用ORM?你問了改進代碼的方法,使用ORM是這樣做的一種方式。 –

+0

我們不使用ORM是因爲它是一個大項目,它會更加複雜。但我需要重新構建代碼plz的建議。 – TimeIsNear

0

我通常從資源文件中加載它。這給你一些自由來改變查詢(這在你不需要動態生成if塊的情況下)。在源代碼中,我所使用的格式化結束我的,以便註釋行線,以避免我的IDE來連接或者把它們都放在一個像這樣的:

String sql = "select " + // 
    " * " + // 
    "from "+ // 
    " employee " + // 
    "where " + // 
    "  salary > :minSal " + // 
    " and startDate > :minStartDate"; 

而且在條件部分的情況下,我只是用,如果添加它塊。但是對於where語句,我只需添加一個默認的「1 = 1」以便繼續處理其他限制,因此如果沒有其他限制,查詢仍然有效。假設兩種情況都添加有條件的SQL語句波紋管:

String sql = "select " + // 
    " * " + // 
    "from "+ // 
    " employee " + // 
    "where 1 = 1 "; 

直到在這裏你有你的基地SQL,有效的,這意味着如果不加條件仍然是有效的。

假設你將增加限薪以防萬一,如果它被告知:

if (salary != null) { 
    sql += "and salary > :minSalary"; 
    parameters.put("minSalary", salary); 
} 

正如你可以在相同的條件下看到我添加了一個新的表達我的SQL和參數的地圖,這將是稍後用於執行以將參數設置爲查詢,這樣可以避免創建第二個if語句來設置此參數。

您可以採用的另一種方法是構建整個SQL,然後在執行之前詢問準備好的語句需要哪些參數作爲輸入並提供它們。在Java中,你可以做到這一點: http://download.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html#getParameterMetaData%28%29

我知道這是不是這樣的,但如果使用ORM,是常見的有疑問建設者和這原來這個任務要容易得多,例如Hibernate中,你可以擁有的東西像:

List cats = sess.createCriteria(Cat.class) 
    .add(Restrictions.like("name", "F%") 
    .addOrder(Order.asc("name")) 
    .addOrder(Order.desc("age")) 
    .setMaxResults(50) 
    .list(); 

因爲它是在記載: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html

這意味着你可以這樣做:

Criteria c = sess.createCriteria(Cat.class) 
    .addOrder(Order.asc("name")) 
    .addOrder(Order.desc("age")) 
    .setMaxResults(50); 
if (name != null) { 
    c.add(Restrictions.like("name", name); 
} 
List cats = c.list(); 
0

你可以做的一個小改變是將dropdownlist的value屬性設置爲typeA,TypeB等。並且刪除最初的if條件和變量。

如:在現實中

if(ddlType.selectedValue.toString()=="typeA") 
    finalQuery = queryA; 
if(ddlType.selectedValue.toString()=="typeB") 
    finalQuery = queryB; 
+0

謝謝arjunshetty,這是我正在等待的這種忠告! – TimeIsNear

相關問題