Parameter in Statements bei verschiedenen Datenbanken



  • Hallo Genossen,

    gegeben ist MSSQL-Server und dBase-Datenbank

    Mittels Factory in C# wird entweder eine SqlConnection oder OleDbConnection
    erstellt, welche auf die allgemeine DbConnection führt. Aus dieser wird das
    DbCommand Objekt abgerufen um daran Parameter zu binden bevor die Abfrage
    ausgeführt wird.

    Parameter an MSSQL-Server werden mit '@ParameterName', an dBase-Datenbank
    mit '?' angegeben.

    In einem Statement kann es nun vorkommen, dass ein ParameterName zweimal
    verwendet wird. Das hat zur Folge bei MSSQL-Server, dass durch setzen eines
    Parameters im DbCommand-Objekt alle gleichnamigen Parameter im Statement diesen
    Wert zugewiesen bekommen.

    Beim dBase-Datenbank hingegen müsste dieser Parameter 2 mal im DbCommand-Objekt
    angegeben werden, da hier keine Ersetzung durch Namenserkennung sondern durch Ersetzung der '?'-Zeichen erfolgt.

    Der Name des Parameters spielt auch keine Rolle, es muss nur die Anzahl und Reihenfolge beachtet werden.

    Ziel soll sein, dass im Quelltext auf diesen Unterschied nicht geachtet werden muss.

    Das Statement soll allgemeingültig formuliert werden. Bsp. ( evtl. etwas wenig sinnvoll 🙂 )

    SELECT * FROM Kunden WHERE kdnr=@KDNR AND kdnr >= @KDNR

    Es soll genügen den Parameter so anzugeben.
    cmd.AddParameter("KDNR", value);
    ( funktioniert nur für MSSQL-Server, da alle gleichnamigen ersetzt werden )

    Für OleDbConnection würde das Statement manipuliert
    SELECT * FROM Kunden WHERE kdnr=? AND kdnr >= ?

    dafür müssen aber 2 Parameter angegebn werden, wobei der Name bedeutungslos ist
    cmd.AddParameter("KDNR", value);
    cmd.AddParameter("KDNR2", value);
    ( funktioniert für MSSQL-Server und dBase-OleDBConnection, da KDNR2 bei
    MSSQL-Server verworfen wird und für dBase die Anzahl/Reihenfolge der Parameter
    korrekt ist )

    Nun meine Frage. 😃

    Gibt es für das Auffinden von mehrfach vorkommenden Zeichenfolgen und deren
    Position zwischen anderen "gültigen" Zeichenfolgen eine Library oder gibt's
    da nix fertiges.
    Ich habe versucht mit Regex.Matches Ansätze zu finden, bisher erfolglos.

    So wie die Ersetzungen @NAME => ? ( mit Regex.Replace ) erfolgen muss die Liste
    an Parametern auch entsprechend manipuliert werden. ⚠

    Edit, meine "manuelle" Lösung sieht derzeit so aus. Evtl. gibt's etwas eleganteres 😕

    static List<int> FindPositionsOfText(string textToFind, string textToSearch)
            {
                List<int> result = new List<int>();
    
                int lastIndex = 0;
                while (textToSearch.IndexOf(textToFind, lastIndex) > -1)
                {
                    result.Add(textToSearch.IndexOf(textToFind, lastIndex));
                    lastIndex = result[result.Count - 1] + textToFind.Length;
                }
                return result;
            }
            static Dictionary<String, object> buildOleDbParameters(String query, Dictionary<String, object> parameters)
            {
                Dictionary<Int32, String> positions = new Dictionary<Int32, String>();
                Dictionary<String, object> newParameters = new Dictionary<string, object>();
    
                foreach (var key in parameters.Keys)
                {
                    foreach (int index in FindPositionsOfText(key, query))
                    {
                        positions.Add(index, key);
                    }
                }
                var list = positions.Keys.ToList();
                list.Sort();
                foreach (var key in list)
                {
                    string valueKey;
                    if (positions.TryGetValue(key, out valueKey))
                    {
                        newParameters.Add(key.ToString(), parameters[valueKey]);
                    }                
                }
                return newParameters;
            }
    

Log in to reply