Avatar billede dkkarpen Nybegynder
01. september 2005 - 19:28 Der er 2 kommentarer og
1 løsning

SQL Builder i C#

Halløj

Fra de gode gamle ASP dage har jeg et script der kunne generere en sql streng til brug for søgning boolske operatorer. Er der en der har et lignende script i C#?

Scriptet ser således ud:

'Definerer de to variabler, der benyttes af GetWord proceduren. Se den for
'yderligere informationer.


Dim CurWord, CurWordLen

'Sættes en konstant, som benyttes til at indsættes det rette wildcard i
'SQL udtrykket.
'Bruges VB, er wildcard'et "*"
'Bruges ASP, er wildcard'et "%"
Const ACCESS_WILDCARD = "%"

Function SQLClause(SearchString, TableList)
    'Erklær en række variabler, der skal bruges i funktionen:
    '  bln: Hvis denne er True, indsættes der ikke nogen boolske udtryk i den endelige
    '      SQL-sætning. Dvs, at man ikke får en fejl, hvis der står "and or" i søge-
    '      udtrykket. Her ignoreres "or". Brugen af "not" har intet med dette at gøre.
    '  curOut / curOut2: Temporære variabler, der benyttes når man skal tilføje en
    '                    streng til søgeudtrykket.
    '  l(): Et array, der indeholder en liste over tabeller.
   
    Dim bln, curOut, curOut2
   
    'Opsplit argumentet TableList til det dynamiske array l()
    l = Split(TableList, ",")
    'Der skal ikke være nogle boolske udtryk til at starte med (dvs. vi kan ikke starte
    'med "and" eller "or". "Not" er naturligvis en undtagelse.
    bln = True
    'Evaluér SearchString således at der ikke opstår fejl. Læs funktionen for mere info
    'om denne evaluering.
    SearchString = SQLValSearchString(SearchString)
   
    'Efterhånden som dele af søgeudtrykket evalueres, slettes det fra strengen. Når der
    'ikke er mere af udtrykket (Len(SearchString)=0), stoppes løkken, og SQL betingelsen
    'skulle være parat.
    Do While Len(SearchString) > 0
        'Hent det næste "ord" fra SearchString. Et ord kan også være (, ) eller en
        'længere streng indgrænset af "".
        'Eksempelvis bliver    (hej and sa) or "med dig"
        ' -  (
        ' -  hej
        ' -  and
        ' -  sa
        ' -  )
        ' -  or
        ' -  med dig
        'GetWord er en procedure, som sætter det nye ord og længden af den del af
        'SearchString, der bruges til at finde dette ord, i CurWord og CurWordLen.
        GetWord SearchString
        Select Case CurWord
            'Hvis CurWord er ( eller ) skal parentesen sådan set bare tilføjes til
            'SQL udtrykket. Med det forbehold at der skal være et "and" eller et "or"
            'foran venstreparenteser. Dette gælder naturligvis ikke i starten, men
            'værdien af bln tager højde for dette.
            Case "("
                If Not bln Then Out = Out & " AND "
                Out = Out & "("
            Case ")"
                Out = Out & ")"
               
            'Hvis der endnu ikke er tilføjet et "and" eller et "or" til SQL udtrykket
            'siden sidste LIKE-sammenligning (indikeret ved værdien af bln), skal der
            'tilføjes CurWord, hvis dette er "and" eller "or".
            Case "and", "or"
                If Not bln Then
                    Out = Out & " " & UCase(CurWord) & " "
                    'bln opdateres naturligvis nu da et "and" eller "or" er tilføjet
                    bln = True
                End If
           
            'Hvis CurWord er "not" er det anderledes. Der skal være et "or" eller et
            '"and" foran "not" (igen indikeret ved bln).
            Case "not"
                If Not bln Then Out = Out & " AND "
                Out = Out & "NOT "
                'bln opdateres naturligvis nu da et "and" eller "or" er tilføjet
                bln = True
           
            'Og så dét, det i virkeligheden handler om
            Case Else
                'Hvis der endnu ikke er blevet tilføjet et "and" eller "or" siden sidste
                'LIKE-sammenligning, gøres det nu.
                If Not bln Then Out = Out & " AND "
                'curOut sættes til LIKE-sammenligningen. $$$ er stedet, hvor navnet på
                'databasen i posten skal tilføjes.
                curOut = "($$$ LIKE '" & ACCESS_WILDCARD & CurWord & ACCESS_WILDCARD & "')"
                'curOut2 sættes til en tom streng. curOut2 skal indeholde denne specifikke
                'LIKE-sammenligning for alle posterne, der er angivet i parametret TableList.
                curOut2 = ""
                'En LIKE-sammenligning for hver post tilføjes til curOut2 og de sammenkædes
                'med " OR ".
                For i = LBound(l) To UBound(l)
                    curOut2 = curOut2 & Replace(curOut, "$$$", l(i))
                    If i <> UBound(l) Then curOut2 = curOut2 & " OR "
                Next
                'Endeligt sættes der parenteser omkring.
                Out = Out & "(" & curOut2 & ")"
                'Og bln sættes til False (dvs. der vil blive tilføjet enten et "and" eller
                'en ) som det næste.
                bln = False
        End Select
       
        'Det af strengen, der er blevet evalueret skæres væk.
        For i = 1 To CurWordLen
            SearchString = Cut(SearchString, 1)
        Next
    Loop
   
    'Out indeholder nu det, der skal bruges, så der sættes () omkring udtrykkes,
    'og funktionen returnerer.
    SQLClause = "(" & Out & ")"
End Function

Function SQLValSearchString(SearchString)
    'Undgå SQL problemer med en enkelt apostrof.
    SearchString = Replace(SearchString, "'", "''")
   
    'Konvertér tabs til mellemrum
    SearchString = ReplaceEx(SearchString, vbTab, " ")

'/***
'Her følger der nogle omskrivninger af de boolske operatorer, som
'for så vidt er ligegyldige for denne fase, men det er meget sjovt
'at tillade brugen at bruge dem.
'Bemærk at ReplaceEx bruges, hvorved der tages højde for anførselstegn
'Der kan være ulemper ved brugen af nogle af disse.
'eksempelvis kan et ord med bindestreg blive omformuleret til noget
'med NOT. Vælg selv hvilke operatorer, du vil bruge.
'Har du flere ideer til operatorer: Send en mail, så andre kan få
'noget ud af din ide.
    'Koverter enkeltstående && til AND
    SearchString = ReplaceEx(SearchString, "&&", " and ")
    'Koverter enkeltstående & til AND
    SearchString = ReplaceEx(SearchString, "&", " and ")
   
    'Koverter enkeltstående || til OR
    SearchString = ReplaceEx(SearchString, "||", " or ")
    'Koverter enkeltstående | til OR
    SearchString = ReplaceEx(SearchString, "|", " or ")
   
    'Koverter enkeltstående + til AND
    SearchString = ReplaceEx(SearchString, "+", " and ")
    'Koverter enkeltstående - til NOT
    'SearchString = ReplaceEx(SearchString, "-", " not ")
   
    'Koverter enkeltstående ! til NOT
    SearchString = ReplaceEx(SearchString, "!", " not ")
'***/

   
    'Sørg for at kunne nøjes med én sammenligning ligemeget
    'hvordan brugeren har defineret søgningen. "AND", "and"
    'og "aNd" skulle gerne være det samme.
    SearchString = LCase(SearchString)
   
    'Definer de variabler, der skal benyttes til at
    'angive status i konverteringen.
   
    Dim Pos
   
    'Hvis der er et ulige antal "'er opstår der problemer.
    'Dette omgås ved at fjerne det sidste ", der forekommer.
    'Nogen andre løsningsforslag?
    If Not IsEqual(AntalAfTegn(SearchString, """")) Then SearchString = Cut(SearchString, InStrRev(SearchString, """"))
   
    'Søgestrengen trimmes. Der skal ...
    '...aldrig være mere end ét mellemrum mellem to ord.
    '...aldrig være mellemrum efter en VParentes.
    '...aldrig være mellemrum før en HParentes.
    '...aldrig være mellem i start eller slut
   
    'Start + slut
    SearchString = Trim(SearchString)
   
    'Ikke to mellemrum efter hinanden
    Do While InStrEx(SearchString, "  ", 1) > 0
        SearchString = ReplaceEx(SearchString, "  ", " ")
    Loop

'/***
'Bemærk at dobbeltmellemrum er fjernet; der kræves ingen løkke
    'Ikke noget mellemrum efter VParentes
    SearchString = ReplaceEx(SearchString, "( ", "(")
    'Ikke noget mellemrum før HParentes
    SearchString = ReplaceEx(SearchString, " )", ")")
'***/

    'Mens der er højre-parenteser før venstreparenteser, skal
    'disse højreparenteser fjernes. Ellers kan der senere opstå
    'problemer. Der tages højde for anførselstegn, og der sørges
    'nedenfor for at der er lige mange v- og h-parenteser.
    Do While InStrEx(SearchString, ")", 1) < InStrEx(SearchString, "(", 1) And InStrEx(SearchString, ")", 1) <> 0
        SearchString = Cut(SearchString, InStrEx(SearchString, ")", 1))
    Loop
   
    'Hvis der er flere )'er end ('er skal der tilføjes nogle ('er.
    'Der skal være lige mange venstre- og højre parenteser, ellers
    'opstår der problemer senere. Bemærk i øvrigt at AntalAfTegnEx
    'tager højde for anførselstegn. Derfor tælles parenteser inden
    'for sådanne ikke med i udregningen
    Do While AntalAfTegnEx(SearchString, "(") < AntalAfTegnEx(SearchString, ")")
        SearchString = "(" & SearchString
    Loop
    'Og så ellers omvendt...
    Do While AntalAfTegnEx(SearchString, ")") < AntalAfTegnEx(SearchString, "(")
        SearchString = SearchString & ")"
    Loop

    SQLValSearchString = SearchString
End Function

'Returnerer antal af et givent Tegn i Str.
Function AntalAfTegn(Str, Tegn)
    For i = 1 To Len(Str)
        If Mid(Str, i, 1) = Tegn Then AntalAfTegn = AntalAfTegn + 1
    Next
End Function

'Returnerer antal af et givent Tegn i Str, der ikke er indgrænset af "".
Function AntalAfTegnEx(Str, Tegn)
    Dim Anforsel
    For i = 1 To Len(Str)
        If Mid(Str, i, 1) = """" Then Anforsel = Not Anforsel
        If Mid(Str, i, 1) = Tegn And Not Anforsel Then AntalAfTegnEx = AntalAfTegnEx + 1
    Next
End Function

'Returnerer placeringen af String2 i String1, der ikke er indgræset af "". Starter ved placering StartWith
Function InStrEx(String1, String2, StartWith)
    Dim l1, l2, i, Anforsel
    l1 = Len(String1)
    l2 = Len(String2)
    If l2 = 0 Then
        InStrEx = 0
        Exit Function
    Else
        For i = StartWith To l1 - l2 + 1
            If Mid(String1, i, 1) = """" Then Anforsel = Not Anforsel
            If Mid(String1, i, l2) = String2 And Not Anforsel Then
                InStrEx = i
                Exit Function
            End If
        Next
    End If
    InStrEx = 0
End Function

'Returnerer en streng, hvor sFind er erstattet med sReplace i Str.
'Dog hvor sFind ikke er indgrænset af ""
Function ReplaceEx(Str, sFind, sReplace)
    Dim Pos, Start
    Pos = InStrEx(Str, sFind, 1)
    Do While Pos > 0
        For i = 1 To Len(sFind)
            Str = Cut(Str, Pos)
        Next
        Str = Insert(Str, sReplace, Pos)
        Pos = InStrEx(Str, sFind, Pos + Len(sReplace))
    Loop
    ReplaceEx = Str
End Function

'Returnerer en boolsk værdi, der indikerer om n er et lige tal.
Function IsEqual(n)
    IsEqual = ((n / 2) = Int(n / 2))
End Function

'Returnerer er den streng, hvor karakteren på position Pos fra strengen Str er skåret væk.
Function Cut(Str, Pos)
    Cut = Left(Str, Pos - 1) & Right(Str, Len(Str) - Pos)
End Function

'Indsætter strengen From i Into på position Pos. Returnerer denne streng.
Function Insert(Into, From, Pos)
    Dim Before, After
    If Pos < 1 Then Pos = 1
    If Len(Into) = 0 Then
        Insert = From
    ElseIf Pos > Len(Into) Then
        Insert = Into & From
    Else
        Before = Left(Into, Pos - 1)
        After = Right(Into, (Len(Into) - Pos) + 1)
        Insert = Before & From & After
    End If
End Function

'Henter det første ord fra Str, og sætter denne værdi i CurWord. Et "ord" kan være
'  (
'  )
'  et ord indgrænset af to mellemrum
'  en streng indgrænset af to ""
'CurWordLen sættes til længden af det udtryk fra Str, der benyttes til at bestemme CurWord.
'Eksempelvis medtages "'er ikke i CurWord, mens de tæller med i CurWordLen.
Sub GetWord(Str)
    Dim i, CurSubStr, Anforsel, Out
    For i = 1 To Len(Str)
        CurSubStr = Mid(Str, i, 1)
        If CurSubStr = """" Then
            Anforsel = Not Anforsel
        Else
            If (CurSubStr = " " Or CurSubStr = "(" Or CurSubStr = ")") And Not Anforsel Then
                If Len(Out) > 0 Then
                    i = i - 1
                    Exit For
                ElseIf CurSubStr = "(" Or CurSubStr = ")" Then
                    Out = CurSubStr
                    Exit For
                End If
            Else
                Out = Out & CurSubStr
            End If
        End If
    Next
    CurWord = Out
    CurWordLen = Min(i, Len(Str))
End Sub

'Returnerer den mindste værdi af m og n.
Function Min(m, n)
    If m < n Then
        Min = m
    Else
        Min = n
    End If
End Function
Avatar billede snepnet Nybegynder
03. september 2005 - 13:59 #1
var det noget at benytte en or-mappper istedet?
ellers måske :
http://www.codeproject.com/csharp/Sql_Filter_with_C_Sharp.asp
mvh
Avatar billede dkkarpen Nybegynder
05. september 2005 - 23:52 #2
Nice - tak.
Avatar billede snepnet Nybegynder
06. september 2005 - 08:35 #3
var så lidt :o) - vil du have et svar på den?
mvh
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester