2009-02-24 19 views
9

Piszę trochę kodu C++, który używa biblioteki sqlite3. Używam przygotowanej instrukcji, do której wiążę zmienną w czasie wykonywania.przygotowane instrukcje sqlite - jak debugować

Jak sprawdzić zapytanie SQL w oświadczeniu po powiązaniach?

Na przykład poniższy kod nie zwraca wiersza. Używając wstępnie napisanego ciągu znaków i sqlite3_exec, otrzymuję oczekiwane rezultaty.

sqlite3_stmt *statement; 
const char *query = "SELECT * FROM foo WHERE (name='?');"; 
sqlite3_prepare_v2(db, query, strlen(query), &statemtnt, NULL); 
sqlite3_bind_text(statement, 1, "bar", -1, SQLITE3_STATIC); 
int result = sqlite3_step(statement); 
// expected: result = SQLITE_ROW 
// actual: result = SQLITE_DONE 

edit: Jak Ferdinand nizej, problem w zapytaniu Powyższe cytaty wokół?. Jednak w przyszłości nadal chciałbym wiedzieć, jak sprawdzić sqlite3_stmt dla rzeczywistego zapytania, które zostanie wykonane.

Odpowiedz

1

Trzeci parametr sqlite3_bind_text ma być wartością, którą chcesz powiązać - w swoim kodzie próbujesz powiązać zapytanie z samym sobą!

Gubić średnik na końcu SELECT.

+0

Niestety, miał literówkę podczas pisania pytania. Tak, nie, to nie jest prawdziwy problem, przepraszam –

+0

Wierzę, że średnik jest wymagany –

6

Zapytanie SQL nie zmienia się po powiązaniach - zmienne nie są wstawiane do łańcucha SQL ani nic.

Oprócz tego, co powiedział Neil, upuść znaki cudzysłowu wokół? placeholder:

"SELECT * FROM foo WHERE name = ?" 

W przeciwnym razie SQLite nie zastąpi znaku zapytania, ale potraktuje go jako ciąg "?".

+1

Dzięki, problem był rzeczywiście cytatów wokół?. –

+0

Wiem, że ciąg sql się nie zmienia (mimo wszystko zadeklarowałem, że to const). ALE, instrukcja zmienia się. Czy istnieje sposób, aby zobaczyć, jakie zapytanie trafi do DB po powiązaniach, patrząc na oświadczenie? –

+0

Masz na myśli, że chcesz sprawdzić drzewo parsowane generowane przez SQLite? Nie sądzę, że możesz to zrobić bez zagłębiania się w kod źródłowy SQLite ... –

-1

Nie wiem tak dobrze, ale faktyczne zapytanie może zostać zarejestrowane lub możesz przełączyć przełącznik, aby go zarejestrować.

1

Tak, można to zrobić poprzez zdefiniowanie funkcji profilu tak:

static void profile(void *context, const char *sql, sqlite3_uint64 ns) { 
fprintf(stderr, "Query: %s\n", sql); 
fprintf(stderr, "Execution Time: %llu ms\n", ns/1000000);} 

Następnie tuż po otwarciu bazy danych za pomocą sqlite3_open, zrobić to wezwanie:

sqlite3_profile(fDBLink, &profile, NULL); 
+0

Po prostu próbowałem tego; nie pokazuje wyniku wiązań, jak się wydaje, pragnienie. – kasterma

+0

Dobra sugestia, ale nie pokazuje powiązanych argumentów – inversus

Powiązane problemy