2011-06-24 10 views
1

私は、SQLのwhere節にかなり近いところにユーザー入力の検証ロジックを取り入れています。ユーザーがドロップダウンの組み合わせから選択することができますページでwhere句に「よく似ている」データの妥当性確認

(「 - 」文字が最終節で、空白文字を表します):

DropDown1 DropDown2  DropDown3 DropDown4 DropDown5 DropDown6 

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

残念ながら、私は上の任意のハード要件はありません。それは少数のその寿検証に

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

を渡すべきである:(

数「節のSQLのように振る舞う」すべきである以外に、この句を検証する方法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パーサを話す人がこの '制限された' where節のより良い解決策になると思っています。

+0

ユーザーは、「行」ごとにカスタムの値と基準を入力しますか?あるいは、あらかじめ定義された値/基準のリストから選択するだけですか? – BumbleB2na

+0

問題にさらに制約を加えない限り、正規表現はブラケットのバランスを検証できません – Neowizard

+0

ああ、ブラケットが必要なことを意味しています。あなたはここでも正規表現は必要ありません。 – BumbleB2na

答えて

0

注:ユーザーに左括弧のドロップダウンメニューで、より多くのオプションと右括弧のドロップダウンリストを与えればあなたのソリューションはのみ機能します、(A == B AND B != C OR (A == B OR (A == C))):ユーザーは以下のように声明を行う必要がある状況では。左括弧のドロップダウンには、次のオプションが含まれている必要があります。'(', '((', '(((', '(((('と、行内の4つの左括弧でキャップを外すことができます。右括弧のドロップダウンも同じに見えるはずです。

リピーター内にドロップダウンを配置すると、.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 

最新のリピータ行が有効になっていて、以前のすべての行は、彼らが編集したい行になるまで、それぞれの最新の行を削除するには、ユーザーを強制的に、禁止されますので、それを作ることができます有効になりました。これにより、検証が簡素化され、最新の行のみが対象となり、前のすべての行が検証されたことがわかります。最新の行が有効な場合、SQL WHERE句として文字列全体を実行することは安全です。

注:私は提案のように、前の行をロックダウンした場合、ユーザーが最新の行を削除する場合、その後、あなたはnumUnclosedLeftBracketsの値をチェックする必要がありますと、これは少し異なるアプローチを必要とするかもしれない、など:保存します未処理の左括弧を含む各行のリピータ行インデックス。

+0

これはうまくいくだろうが、誰かが '(A && B)||(B || C)'をどうやって指定できるだろうか? –

+0

は、かっこの必要性を認識しました。どのように表示するかをお伝えしました。 – BumbleB2na

+0

こんにちは、ありがとうございます。私はそれを調べて、私のニーズに合わせて遊ぶことができるかどうかを見ていきます。 (=ヴァル 基準)AND (criteria1 = val1と) 注意すべき 一つのマイナーな事は、結果がグリッドがベースとなると私は、最終的な結果をラップし、ユーザーが のような句を作ることができるので、検証します 私はあなたのコードは、各行に演算子が含まれているという要件を除いてこれを処理すると思います...確かに大きな問題ではなく、私は編集したり変更したりすることができます。もう一度あなたの助けに感謝します!ありがとうございます。 – GargantuanTezMaximus

0

あなたの句は、SQL where句のようにフォーマットされている場合、私は...私は同様の質問を他の人々を見てきたようにそこに誰か他の人に有用である可能性が考えていたことを、自分の際

をつまずいたソリューションこれはあなたが句...

ホープこのことができます有効なSQLを持っているすべてのエラー出て合格した場合

SET PARSE ONLY 

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

:あなたはの線に沿って手順を使用して、データベースに対するコールを行うことによって、それを検証することができます誰か。