Laden...

[gelöst] Parametrisierte Query mit Like

Erstellt von Lion1984 vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.683 Views
L
Lion1984 Themenstarter:in
770 Beiträge seit 2006
vor 14 Jahren
[gelöst] Parametrisierte Query mit Like

verwendetes Datenbanksystem: <MS SQL2005>

Hallo Forum,

ich habe eben ein interessantes Problem festgestellt, dass ich bei einer Suche nicht lösen konnte. (Meine Suche war wohl alles mögliche mit SQL, 2005, Like) aber da gibt es wohl bei google zahlreiche Links.

Mein Problem ist, dass ich in meiner Anwendung eine Query zusammenbastle mit einigen Parameter. Dass "passt" auch so ziemlich, laut Profiler kommt dieser SQL String an der Datenbank an:

exec sp_executesql N'SELECT * FROM [TblA] WHERE [Column1] Like @Para Order by 1, 2',N'@Para nvarchar(9)',@Para=N'chervin'

Dieser findet nichts, warum habe ich schon gefunden. da der gesuchte Datensatz ein Leerzeichen hinten dran hat, also "chervin ". Aber wenn ich nun den SQL String herauskopiere und @Para durch "chervin" ersetze, also

SELECT * FROM [TblA] WHERE [Column1] Like 'chervin'

So findet er den gesuchten Datensatz, meine Frage, sollten eigentlich nicht beide Abfragen das selbe ergeben?

Es kann mit u.a. sein, dass ich bei meiner Suche das "goldenen" Schlüsselwort nicht gefunden habe bzw. gar vergessen habe, so steinigst mich nicht, wenn ihr es durch google (oder ähnliches findet) sondern lehrt mich bessere Schlüsselwörter 😃

Lion

lg Lion

1.564 Beiträge seit 2007
vor 14 Jahren

Hängt vom ANSI_PADDING der aktuellen Connection ab. Aber fehlt deinem Parameter nicht einfach ein "%". Statt "chervin" also nach "chervin%" suchen?

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

L
Lion1984 Themenstarter:in
770 Beiträge seit 2006
vor 14 Jahren

Hallo Florian (wiedermal 😃 )

Dass % fehlt, ist mir klar, aber was mich verwirrt ist eben, dass der Datensatz einmal gefunden wird, und einmal nicht, und beides wird ohne % verwendet.

Lion

lg Lion

1.564 Beiträge seit 2007
vor 14 Jahren

Hi Lion

Welchen Datentyp haben deine Spalten?

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

L
Lion1984 Themenstarter:in
770 Beiträge seit 2006
vor 14 Jahren

varchar(25)

lg Lion

4 Beiträge seit 2009
vor 14 Jahren

weil es eben einen Unterschied macht, ob Du mit LIKE oder = suchst.
Wenn Du angibst, es soll "=" sein, dann spielt das Leerzeiche eine Rolle, wie Du ja schon selbst schreibst.

L
Lion1984 Themenstarter:in
770 Beiträge seit 2006
vor 14 Jahren

und es macht wohl einen Unterschied, ob man die Threads durchliest oder nicht 😃

Ich will kein = haben, ich habe zwei Abfragen die das selbe sein sollten. Durch eine gebastele Query kommt der oben genannte String mit Parameter an. Dieser findet nichts in der Datenbank, kopiere ich den String und ersetze den Parameter mit dem Wert, den er hat, dann finde ich den Datensatz.

Ich will wissen, wieso die Version mit Parameter nichts findet, aber die Version ohne schon, obwohl es die gleiche Abfrage sein sollte!

@Florian, du hattest die Connection erwähnt, ich habe beide Statements mit der selben Connection durchgeführt mit dem selben oben genannten Ergebniss.

Lion

lg Lion

1.564 Beiträge seit 2007
vor 14 Jahren

Hallo Lion

Mit der Connection hatte ich mich wohl getäuscht, sorry. Habe es gerade nochmal getestet. Ich bekomme auch aus C# Werte mit hinten angefügten Leerzeichen zurück:

         string cnStr = @"
                     Server=.;
                     Database=Sandbox;
                     Trusted_Connection=true;
                     ";
         using (SqlConnection cn = new SqlConnection(cnStr))
         {
            cn.Open();

            string sql = @"
                  DECLARE @t TABLE (Txt CHAR(100));

                  INSERT INTO @t
                               SELECT 'abc'
                     UNION ALL SELECT 'abc '

                  SELECT COUNT(*) FROM @t WHERE Txt LIKE @p
                  ";

            using (SqlCommand cmd = new SqlCommand(sql, cn))
            {
               cmd.Parameters.Add("@p", SqlDbType.Char, 100).Value = "abc";

               int count = (int)cmd.ExecuteScalar();
               Console.WriteLine("Count: {0}", count);
            }
         }

Bist du sicher, dass nicht irgendwo anders der Wurm drinnen ist?

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

L
Lion1984 Themenstarter:in
770 Beiträge seit 2006
vor 14 Jahren

Hallo Florian,

ich schreibe erst jetzt da ich am Freitag frei hätte und paar Tage im Lände unterwegs war 😃

Also das "Problem" konnte ich nachstellen:
einfach eine Tabelle erstellen mit zwei Spalten: ID, Value
ID ist int, primärschlüssel und erhöht sich automatisch
Value ist varchar(25).

Anschließend habe ich zwei Einträge erstellt (Value ist 'test' und 'test_' _ = Leerzeichen).

Die Abfrage

SELECT * FROM myTest WHERE Value Like 'test'

liefert beide Ergebnisse.

Die Abfrage

exec sp_executesql N'SELECT * FROM myTest WHERE Value Like @Para Order by 1, 2',N'@Para nvarchar(25)',@Para=N'test'

liefert nur ein Ergebniss.

Aber ich habe eben den Parameter von nvarchar auf varchar geändert, hier liefert er wieder beide Ergebnisse. Kann mir das jemand Erklären? Ich wüßte aktuell nicht mehr, nach was ich suchen könnte.

Ich hab mal ein Screen angehängt wo man die 3 Abfragen sieht, eventuell habe ich mich ja auch undeutlich ausgedrückt 😃

Lion

lg Lion

1.564 Beiträge seit 2007
vor 14 Jahren

Hi Lion

Dass du einmal beide und einmal nur einen Wert zurückbekommst liegt daran, dass Unicode sich anders verhält als Non-Unicode.

Deine Abfrage im SSMS liefert beide Werte zurück weil du dein Suchkriterium als VARCHAR übergibst. Führe mal folgende beiden Statements aus. Das zweite liefert auch nur eine Zeile zurück weil das "N" vor dem Text diesen als Unicode übergibt:

SELECT *, REPLACE(Value, ' ', '#') FROM myTest WHERE Value LIKE 'test'
SELECT *, REPLACE(Value, ' ', '#') FROM myTest WHERE Value LIKE N'test'

.NET übergibt deinen Parameter als NVarChar, weil du deinen SqlParameter nicht korrekt initialisiert hast. Du solltest auf Text-Parametern immer sowohl den exakten Typen (also Char, VarChar, NChar oder NVarChar) und die korrekte Länge des Parameters definieren.

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

L
Lion1984 Themenstarter:in
770 Beiträge seit 2006
vor 14 Jahren

Somit hätten wir das Problem gefunden samt Lösung, Danke.

Ich dachte immer, bei einem Parameter wäre es egal, "Like" ist doch "Like", egal wie ich es tippe 😃 Ich hatte das erste mal solche Such - Probleme, danke.

Lion

lg Lion