2011-06-24 54 views
1

我正在將用戶輸入的驗證邏輯工作到非常接近sql where子句的地方。「非常相似」的數據驗證where條款

在頁面上,用戶可以從下拉菜單中的組合選擇(其中「 - 」字符表示最終子句中空白字符):

DropDown1 DropDown2  DropDown3 DropDown4 DropDown5 DropDown6 

-   -    -   -   -   - 
(   SomeCriteria =   Value  )   AND 
          <>         OR 

不幸的是,我沒有任何硬要求如何驗證等這一條款比它應該「像一個SQL WHERE子句」 :(

一些應該通過驗證的

(Criteria = Value) 
(criteria1 = Value1 OR Criteria2 <> value2) 
(criteria1 = value1) AND (Criteria2 = value2) 
(criteria1 = value1) OR (Criteria2 = value2 AND criteria3 = value3) 

幾個是守ld驗證失敗:

)Criteria = value) (first character is not '(') 
(Criteria = value( (last character is not ')') 
((Criteria = value) (# of '(' does not match # of ')') 

(Criteria = Value (AND Criteria1 = value1)) ('AND' and 'OR' should not be immediately preceded or followed by a '(' or ')' character. 

任何有關編寫正則表達式來驗證這些選擇的幫助都將得到真正的讚賞。在我看到其他人談論過一個SQL解析器之後,對於這個'restricted'where子句,這會是一個更好的解決方案嗎?

+0

用戶是否要輸入每個「行」的自定義值和標準?或者他們只是從預定義的值/標準列表中進行選擇? – BumbleB2na

+0

沒有正則表達式可以驗證括號的平衡,除非你對問題增加了更多的限制 – Neowizard

+0

噢好吧,我明白你的意思是需要括號。儘管這裏你不需要正則表達式。 – BumbleB2na

回答

0

注:對於有些情況下,用戶需要作出這樣的聲明:(A == B AND B != C OR (A == B OR (A == C))),如果你給用戶的左括號下拉更多的選擇和右括號下拉列表您的解決方案纔有效。左括號中的下拉框應該包含以下選項:'(', '((', '(((', '((((',並且您可以在連續的4個左括號中將其封閉。右括號下拉應該看起來一樣。

你可以把你的下拉列表放入Repeater,這樣.Net會爲每個下拉列表分配一個唯一的ID。

驗證碼:

// this will keep track of left brackets that have not been closed 
int numUnclosedLeftBrackets = 0; 


// changing dropdown instance names for clarity 
ddlLeftBracket == DropDown1; 
ddlCriteria == DropDown2; 
ddlConOperator == DropDown3; 
ddlValue == DropDown4; 
ddlRightBracket = DropDown5; 
ddlExtension == DropDown6; 

Boolean isValidStmt = false; 
Boolean areValidBrackets = false; 
Boolean addAnotherStmt = false; 

// conditional operator dropdown cannot be blank 
if(ddlConOperator.SelectedIndex > 0) 
{ 
    if(ddlConOperator.SelectedValue == "=" && ddlCriteria.SelectedValue == ddlValue.SelectedValue) 
     isValidStmt = true; 
    if(ddlConOperator.SelectedValue == "<>" && ddlCriteria.SelectedValue != ddlValue.SelectedValue) 
     isValidStmt = true; 

    // check if both left and right brackets exist, or if both do not exist. 
    if((ddlLeftBracket.SelectedIndex == 0 && ddlRightBracket.SelectedIndex == 0) || 
       (ddlLeftBracket.SelectedIndex > 0 && ddlRightBracket.SelectedIndex > 0)) 
     areValidBrackets = true; 

    // check if AND, or OR is attached 
    if(ddlExtension.SelectedIndex != 0) 
    { 
     addAnotherStmt = true; 

     // check if brackets need to be validated now that the where clause will continue on 
     if(!areValidBrackets) 
     { 
      // check if left bracket but no right bracket 
      if(ddlLeftBracket.SelectedIndex > 0 && ddlRightBracket.SelectedIndex == 0) 
      { 
       areValidBrackets = true; 
       numUnclosedLeftBrackets += ddlLeftBracket.SelectedIndex; 
      } 
      // check if right bracket but no left bracket 
      if(ddlLeftBracket.SelectedIndex == 0 && ddlRightBracket.SelectedIndex > 0) 
      { 
       // check if left bracket needs closing in a previous value/criteria row and make sure user is not trying to add more right closing brackets than allowed 
       if(numUnclosedLeftBrackets > 0 && (numUnclosedLeftBrackets - ddlRightBracket.SelectedIndex) > -1) 
       { 
        areValidBrackets = true; 
        numUnclosedLeftBrackets -= ddlRightBracket.SelectedIndex; 
       } 
      } 
     } 
    } 
    else 
    { 
     // Since the user has not selected AND or OR, check that there are no unclosed left brackets remaining 
     if(numUnclosedLeftBrackets > 0) 
      areValidBrackets = false; 
    } 
} 
if(!areValidBrackets) 
    // brackets not valid 
else 
    if(!isValidStmt) 
     // not a valid statement 
    else 
     if(addAnotherStmt) 
      // create a new row 
     else 
      // finished and valid - allow saving valid 'WHERE clause' string 

你可以使它所以最近轉發啓用行和以前的所有行被禁止,強制用戶刪除每個最新的行,直到他們想要編輯成爲行啓用。這簡化了驗證,b/c然後你只關心最近的行,知道所有先前的行都被驗證。當最新的行有效時,將整個字符串作爲SQL WHERE子句運行是安全的。

注:如果鎖定了以前的行就像我的建議,那麼當用戶刪除了最近的行,你必須檢查的numUnclosedLeftBrackets的價值,這可能需要一個稍微不同的方法,如:存儲包含未封閉左括號的每行的轉發器行索引。

+0

這會起作用,但是如何指定'(A && B)||(B || C)'? –

+0

意識到需要括號 - 更新顯示如何 – BumbleB2na

+0

嗨感謝您的答覆,我會研究它,看看我是否可以玩弄它,以適應我的需求。 一個要注意的小事是結果將基於網格的,然後我會說唱了最後的結果和驗證,以便用戶可以做出一個條款,像 ( 標準= VAL )和 (標準1 = VAL1) 我想你的代碼會處理這個問題,除了要求每行包含一個操作符... definetly不是一個大問題,我可以編輯和更改。再次感謝您的幫助!謝謝。 – GargantuanTezMaximus

0

一個解決方案,我偶然發現了我自己,我想可能是有用的人別人那裏,因爲我已經看到其他人有類似的問題...

如果您子句格式類似於SQL WHERE子句

SET PARSE ONLY 

SELECT 1 
FROM sys.objects 
WHERE [user generated clause] 

如果通過與出任何錯誤,你有一個有效的SQL WHERE子句...

希望這有助於:您可以通過使用的線沿線的一個程序撥打電話對數據庫進行驗證有人。