Unikaj pojedynczego cudzysłowu do użycia w zapytaniu SQLite

180

Napisałem schemat bazy danych (do tej pory tylko jedną tabelę) oraz instrukcje INSERT dla tej tabeli w jednym pliku. Następnie utworzyłem bazę danych w następujący sposób:

$ sqlite3 newdatabase.db
SQLite version 3.4.0
Enter ".help" for instructions
sqlite> .read ./schema.sql
SQL error near line 16: near "s": syntax error

Linia 16 mojego pliku wygląda mniej więcej tak:

INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there\'s');

Problemem jest znak ucieczki dla pojedynczego cudzysłowu. Próbowałem też podwójnie unikać pojedynczego cudzysłowu (używając \\\'zamiast \'), ale to też nie działało. Co ja robię źle?

jpm
źródło

Odpowiedzi:

294

Spróbuj podwoić pojedyncze cudzysłowy (wiele baz danych tego oczekuje), więc wyglądałoby to tak:

INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there''s');

Odpowiedni cytat z dokumentacji :

Stała łańcuchowa jest tworzona przez umieszczenie ciągu w apostrofach ('). Pojedynczy cudzysłów w ciągu znaków można zakodować, umieszczając dwa pojedyncze cudzysłowy w rzędzie - jak w Pascalu. Znaki ucieczki w stylu C używające znaku ukośnika odwrotnego nie są obsługiwane, ponieważ nie są standardowym kodem SQL. Literały BLOB to literały łańcuchowe zawierające dane szesnastkowe poprzedzone pojedynczym znakiem „x” lub „X”. ... Dosłowną wartością może być również token „NULL”.

Ryan Guill
źródło
8
Rozważ również użycie parametrów powiązanych, jeśli język hosta je obsługuje (większość tak, ale powłoka SQLite nie). SQL byłby wtedy INSERT INTO table_name (field1, field2) VALUES (?, ?)i wartości byłyby dostarczane bezpośrednio (i bez podstawień).
Donal Fellows
1
Czy nie możemy po prostu użyć podwójnych cudzysłowów? na przykład: INSERT INTO nazwa_tabeli (pole1, pole2) VALUES (123, "Witaj"); ?
JacksOnF1re
Ponadto, w zależności od czasu życia łańcucha, pierwszym krokiem może być przekonwertowanie wartości „na” przed ponownym ich podwojeniem.
Gary Z,
44

Myślę, że chciałbyś uciec, podwajając pojedynczy cytat:

INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there''s');
przepełniony
źródło
10

aby zamienić wszystkie (') w ciągu, użyj

.replace(/\'/g,"''")

przykład:

sample = "St. Mary's and St. John's";
escapedSample = sample.replace(/\'/g,"''")
M. Fahri
źródło
6

Na wszelki wypadek, jeśli masz pętlę lub ciąg json, który należy wstawić do bazy danych. Spróbuj zamienić ciąg na pojedynczy cudzysłów. oto moje rozwiązanie. na przykład, jeśli masz ciąg zawierający pojedynczy cudzysłów.

String mystring = "Sample's";
String myfinalstring = mystring.replace("'","''");

 String query = "INSERT INTO "+table name+" ("+field1+") values ('"+myfinalstring+"')";

to działa dla mnie w C # i Javie

Charlie D. Eupeña
źródło
0

W języku C # można użyć następujących poleceń, aby zamienić pojedynczy cytat na podwójny cudzysłów:

 string sample = "St. Mary's";
 string escapedSample = sample.Replace("'", "''");

Wynik będzie następujący:

"St. Mary''s"

A jeśli pracujesz bezpośrednio z Sqlite; możesz pracować z obiektem zamiast ze stringiem i łapać specjalne rzeczy, takie jak DBNull:

private static string MySqlEscape(Object usString)
{
    if (usString is DBNull)
    {
        return "";
    }
    string sample = Convert.ToString(usString);
    return sample.Replace("'", "''");
}
sapbucket
źródło
0

W skryptach basha stwierdziłem, że unikanie podwójnych cudzysłowów wokół wartości było konieczne w przypadku wartości, które mogą być zerowe lub zawierać znaki wymagające znaku ucieczki (np. Myślniki).

W tym przykładzie wartość kolumny A może mieć wartość null lub zawierać łączniki .:

sqlite3 $db_name "insert into foo values (\"$columnA\", $columnB)";
Dan Tanner
źródło