2009-08-18 8 views
41

chcę wykonać kwerendę tak:Android cytaty wewnątrz łańcucha zapytania sql

uvalue = EditText(some user value); 
p_query = "select * from mytable where name_field = '" + uvalue + "'" ; 
mDb.rawQuery(p_query, null); 

jeśli użytkownik wprowadzi apostrof w ich wejście to awarii. Jeśli zmienisz go na:

p_query = "select * from mytable where name_field = \"" + uvalue + "\"" ; 

ulega awarii, jeśli użytkownik wprowadzi podwójny cudzysłów w ich danych wejściowych. i oczywiście zawsze można wprowadzić zarówno pojedyncze, jak i podwójne cudzysłowy.

+0

miannelle, sprawdź te powiązane pytania: http://stackoverflow.com/questions/29699/how-do-i-deal-with-quotes-in-sql http://stackoverflow.co m/questions/387198/escape-double-quotes-in-sql-2005-2008 –

+3

miannelle: Powinieneś popatrzeć na oznaczanie niektórych pytań jako "odpowiedział" – Kurru

Odpowiedz

125

Należy skorzystać z rawQuery metody badaniem selectionArgs parametr:

p_query = "select * from mytable where name_field = ?"; 
mDb.rawQuery(p_query, new String[] { uvalue }); 

To rozwiązuje nie tylko problem cytaty ale również łagodzi SQL Injection.

+5

Chciałbym móc zmodernizować to więcej niż raz! – jrockway

+1

Jest również znacznie szybszy, ponieważ Sqlite nie musi analizować każdego polecenia sql. – tuinstoel

+20

Rzeczywiście powinieneś używać argumentów zapytania. Jednak można również użyć DatabaseUtils, aby uciec od ciągów, w razie potrzeby. Na przykład DatabaseUtils.sqlEscapeString(). To nie jest najlepszy sposób, ale jest dostępny. Może być użyteczne, jeśli próbujesz przekazać surową instrukcję SQL do czegoś zewnętrznego. – lilbyrdie

14

DatabaseUtils.sqlEscapeString działał poprawnie dla mnie. Ciąg jest ujęty w pojedyncze cudzysłowy, a pojedyncze cudzysłowy wewnątrz ciągu stają się podwójnymi cudzysłowami. Próbowano przy użyciu selectionArgs w getContentResolver(). Query(), ale nie działało w ogóle.

2

Czy próbowałeś zastąpić pojedynczą wycenę dwoma pojedynczymi cytatami? Działa to do wprowadzania danych do bazy danych.

+0

Wolałbym użyć górnej odpowiedzi, ale w moim przypadku nie było możliwe do zaprojektowania aplikacji.To działa też – Patrick

1

Mam ten sam problem, ale teraz to jest rozwiązane tylko przez pisanie kodu podobnego w Twoim przypadku, gdy chcesz wstawić wartość uvalue .Następnie napisać jak

uvalue= EditText(some user value); 
uvalue = uvalue.replaceAll("'", "''"); 
p_query = "select * from mytable where name_field = '" + uvalue + "'" ; 
mDb.rawQuery(p_query, null); 

chłodny .. !!

+1

, co jest głupie, zastępujesz słowo "z", co nadal będzie powodowało problemy. – stealthcopter

+0

Być może głupi, ale działa dobrze dla mnie. Dzięki –

+0

@stealthcopter To nie jest głupie, standardową metodą SQL uniknięcia pojedynczego cudzysłowu w ciągu literowym jest jego dwukrotność, więc ''' '' jest literałem SQL, który zawiera jeden pojedynczy cytat. Ręczne odskakiwanie ciągów dla SQL może nie być najlepszym pomysłem, ale wynik jest poprawny w tym przypadku. –

1

Wolę uciec apostrofach i cudzysłowach w każdym INSERT z SQLite tak:

String sqlite_stament = sqlite_stament.replace("'", "''").replace("\"", "\"\""); 
2

należy zmienić

p_query = "select * from mytable where name_field = '" + uvalue + "'" ; 

jak

p_query = "select * from mytable where name_field = '" + android.database.DatabaseUtils.sqlEscapeString(uvalue)+ "'" ; 
+0

Niesamowite i jasne rozwiązanie –

+0

, ale trzeba usunąć cytaty, ponieważ są one domyślnie dodawane –