select nie znajduje pola w którym są cudzysłowy

0

Jest zmienna Zmienna

Jeśli chcę sprawdzić czy w bazie MSSql pole jest równe zmiennej Zmienna:

cmd.CommandText = "SELECT Id FROM Firmy WHERE Pole=@Pole";
cmd.Parameters.AddWithValue("@Pole", Zmienna);

to nie znajduje (a w bazie jest taka wartość), gdy w zmiennej są znaki specjalne typu np cudzysłów "

Jak rozwiązać ten problem z cudzysłowami ? Przecież nie da się wpisywać " bo nie wiadomo jaka jest Zmienna.

Proszę o rozwiązanie

1

Popatrz:

Baza:

use TestDB
go

CREATE TABLE Strings
(
	Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
	String VARCHAR(50) NOT NULL
)

INSERT Strings(String) VALUES('Test One');
INSERT Strings(String) VALUES('Test Two');
INSERT Strings(String) VALUES('Three Test');
INSERT Strings(String) VALUES('Four Test');
INSERT Strings(String) VALUES('te"st th"ree');

Apka na szybkości:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace App
{

    class Program
    {
        static void Main(string[] args)
        {
            using (var conn = new SqlConnection(@"Data Source=THINKPAD\SQLEXPRESS;Database=TestDB;Trusted_Connection=yes;"))
            {
                conn.Open();
                using (var cmd = new SqlCommand("SELECT s.Id, s.String AS Found FROM Strings s WHERE s.String LIKE @param", conn))
                {
                    var searched = "e\"st th\"re";
                    cmd.Parameters.Add(new SqlParameter("@param", '%' + searched + '%'));

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            Console.WriteLine(string.Format("Id: {0}, Found: {1}", 
                                reader["Id"].ToString(), reader["Found"].ToString()));
                        }
                    }
                }
            }
        }
    }
}

Podsumowując: Da się,da! Inaczej ludzie nie mogliby w ogóle używać cudzysłowów, co jest bez sensu.

0

Dziękuję za dokładny opis, ale:

Ręcznie się da, ale w aplikacji zmienna searched może mieć tysiące innych wartości.
Poza tym ja chcę znaleźć pola wyłącznie identyczne jak searched, a Twój przykład to wyklucza.

Za zmienną searched podstawiana jest jakaś wartość typu string, która może zawierać cudzysłowy. Nie znamy tej wartości.
Potrzebna jest funkcja, która sprawdzi czy w zmiennej są cudzysłowy i jeśli tak, to przed każdym umieści backslash (")...

Myślałem, że może jest jakaś funkcja, która to załatwi np searched.WstawBackslashe

...

2

Mówisz całkowitą nieprawdę! Nie potrzebujesz żadnych funkcji usuwających backslashe etc., ponieważ takie rzeczy formatowane są "w locie".
Wstaw do tabeli, którą napisałem takie coś:

insert strings(String) values('Firma "Usługowo-transportowa" Bill Gates')

Następnie uruchom ten program, wpisz w textboksa tę wartość: Firma "Usługowo-transportowa" Bill Gates i wciśnij Enter. Zaświadczam Ci, że zostanie znaleziona!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace App
{
    class Program
    {
        static IList<string> Find(string phrase)
        {
            using (var conn = new SqlConnection(@"Data Source=THINKPAD\SQLEXPRESS;Database=TestDB;Trusted_Connection=yes;"))
            {
                conn.Open();
                using (var cmd = new SqlCommand("SELECT s.Id, s.String AS Found FROM Strings s WHERE s.String = @param", conn))
                {
                    cmd.Parameters.Add(new SqlParameter("@param", phrase));

                    using (var reader = cmd.ExecuteReader())
                    {
                        var result = new List<string>();
                        while (reader.Read())
                        {
                            result.Add(reader["Found"].ToString());
                        }
                        return result;
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            var form = new Form();
            var textbox = new TextBox();
            form.Controls.Add(textbox);
            textbox.Dock = DockStyle.Fill;
            textbox.KeyPress += (sender, e) =>
            {
                if (e.KeyChar == (char)Keys.Return)
                {
                    MessageBox.Show(string.Join(",", Find(textbox.Text)));
                }
            };
            form.ShowDialog();
        }
    }
}

To samo rzecz jasna dotyczy innych znaków specjalnych.

0
cmd.CommandText = "SELECT Id FROM Firmy WHERE Pole=@Pole"; cmd.Parameters.AddWithValue("@Pole", Zmienna.Replace("""", "\"""));
´´´
0

Otóż przepraszam, ale winien jestem dodatkowe wyjaśnienie:

  1. select sprawdzający istnienie rekordu w bazie robiłem dla dwóch pól, czyli były dwa stringi: string1 i string2,
    w string1 były cudzysłowy, a w string2 była nazwa: Śląskie
  2. wartości do stringów brałem z lokalnej bazy MSSql, a selecta robiłem na bazie w internecie (też MSSql)
  3. jak zamieniłem "Śląskie" na "Slaskie" select pięknie działa, czyli to co zapisałem w www zapisało się z innym kodowaniem
  4. dla sprawdzenie zobiłem insert w www dla string1: "ĄąĆćĘꣳÓ󌜯żŹź" i otrzymałem w bazie w internecie: "AaCcEeLlÓóSsZzZz"

Czyli są różne kodowania znaków w obu bazach co generalnie mi trochę komplikuje sprawę.
W local mam Polish_CI_AS,
w www jest SQL_Latin1_General_CP1_CI_AS

Stąd mam kolejne "prośbopytanie" jak postąpić w tej sytuacji?
Co i gdzie wybrać? Czy też zastosować funkcję zmieniającą kodowanie (trochę bez sensu się wydaje)?
Rozsądne byłyby takie same kodowania w obu bazach.
Poproszę dostawcę hostingu o zmianę na Polish_CI_AS
Jeśli nie Polish_CI_AS to co i dlaczego?

P.S.
Serdecznie dziękuję za odpowiedzi Grześkowi i Pawłowi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1