digitalmars.D.learn - Sqlite
- Paul (50/50) Jan 11 2015 Can someone please tell me what I'm doing wrong here, the sql
- ketmar via Digitalmars-d-learn (19/79) Jan 11 2015 if you'll output the error message, you'll see something unusual here:
- Paul (4/9) Jan 11 2015 Thank you, I thought it might be something obvious - that will
- Tobias Pankrath (7/16) Jan 11 2015 Hint: Put the SQL in a file create_people.sql and import it into
- Paul (2/8) Jan 11 2015 Neat, thank you!
- Paul (14/14) Jan 25 2015 I'd like to vary the query based on input but if I try to move
- Tobias Pankrath (4/18) Jan 25 2015 Only string literals convert to const(char)*, because only for
- Paul (7/10) Jan 25 2015 So, as a trivial example, is this how it's done?:
Can someone please tell me what I'm doing wrong here, the sql INSERT statement fails for some reason. I don't fully understand the callback function yet (I borrowed this from a C tutorial on the subject), maybe that is the source of the problem? import etc.c.sqlite3; import std.stdio; //stub extern(C) int aCallback(void *n, int c, char **v, char **col) { return 0; } void main(){ sqlite3 *db; int result = sqlite3_open("myDatabase.db", &db); if (result) { writeln("Failed to open database"); return; } //create table char *msg = null; result = sqlite3_exec(db, "CREATE TABLE people('id INT PRIMARY KEY NOT NULL, surname TEXT NOT NULL');", &aCallback, null, &msg); if (result) { writeln("Failed to create table"); //tidy up on exit sqlite3_close(db); return; } //insert record msg = null; result = sqlite3_exec(db, "INSERT INTO people (id, surname) VALUES (1, 'Smith');", &aCallback, null, &msg); if (result) { writeln("Failed to insert record"); //tidy up on exit sqlite3_close(db); return; } sqlite3_free(msg); sqlite3_close(db); } Many thanks Paul
Jan 11 2015
On Sun, 11 Jan 2015 20:00:03 +0000 Paul via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Can someone please tell me what I'm doing wrong here, the sql=20 INSERT statement fails for some reason. I don't fully understand=20 the callback function yet (I borrowed this from a C tutorial on=20 the subject), maybe that is the source of the problem? =20 =20 import etc.c.sqlite3; import std.stdio; =20 //stub extern(C) int aCallback(void *n, int c, char **v, char **col) { return 0; } =20 void main(){ =09 sqlite3 *db; int result =3D sqlite3_open("myDatabase.db", &db); =09 if (result) {=09 writeln("Failed to open database"); return;=09 } =09 //create table=09 char *msg =3D null; result =3D sqlite3_exec(db, "CREATE TABLE people('id INT PRIMARY=20 KEY NOT NULL, surname TEXT NOT NULL');", &aCallback, null, &msg); if (result) {=09 writeln("Failed to create table"); =09 //tidy up on exit sqlite3_close(db); return; =09 } =09 //insert record msg =3D null; result =3D sqlite3_exec(db, "INSERT INTO people (id, surname)=20 VALUES (1, 'Smith');", &aCallback, null, &msg); if (result) {=09 writeln("Failed to insert record"); =09 //tidy up on exit sqlite3_close(db); =09 return;=09 =09 }=09 =20 sqlite3_free(msg); sqlite3_close(db);=09 =20 } =20 Many thanks =20 Paulif you'll output the error message, you'll see something unusual here: if (result) { import std.conv : to; writeln("Failed to insert record: ", to!string(msg)); //tidy up on exit sqlite3_close(db); =09 return;=09 }=09 "Failed to insert record: table people has no column named id" wow! but it has! or isn't it? yep, it hasn't. the error is here:result =3D sqlite3_exec(db, "CREATE TABLE people('id INT PRIMARY=20 KEY NOT NULL, surname TEXT NOT NULL');", &aCallback, null, &msg);`CREATE TABLE people('...')` is not the syntax you want. i don't know why sqlite is not rejecting it, but the correct one is this: result =3D sqlite3_exec(db, "CREATE TABLE people(id INT PRIMARY "~ "KEY NOT NULL, surname TEXT NOT NULL);", &aCallback, null, &msg); note the single quotes in your code: that is where it all goes wrong. i don't know where you got that quotes from, but this is not a valid SQL syntax for `CREATE TABLE`. ;-)
Jan 11 2015
On Sunday, 11 January 2015 at 20:20:21 UTC, ketmar via Digitalmars-d-learn wrote:note the single quotes in your code: that is where it all goes wrong. i don't know where you got that quotes from, but this is not a valid SQL syntax for `CREATE TABLE`. ;-)Thank you, I thought it might be something obvious - that will teach me to cut and paste code! :D
Jan 11 2015
On Sunday, 11 January 2015 at 20:30:41 UTC, Paul wrote:On Sunday, 11 January 2015 at 20:20:21 UTC, ketmar via Digitalmars-d-learn wrote:Hint: Put the SQL in a file create_people.sql and import it into your code via the import statement: string sql = import("create_people.sql"); // you'll need a correct -J compiler switch That way you can easily test if it's correct on the commandline. It's .read <filename> in the sqlite3 shell.note the single quotes in your code: that is where it all goes wrong. i don't know where you got that quotes from, but this is not a valid SQL syntax for `CREATE TABLE`. ;-)Thank you, I thought it might be something obvious - that will teach me to cut and paste code! :D
Jan 11 2015
On Sunday, 11 January 2015 at 22:19:28 UTC, Tobias Pankrath wrote:Hint: Put the SQL in a file create_people.sql and import it into your code via the import statement: string sql = import("create_people.sql"); // you'll need a correct -J compiler switch That way you can easily test if it's correct on the commandline. It's .read <filename> in the sqlite3 shell.Neat, thank you!
Jan 11 2015
I'd like to vary the query based on input but if I try to move the string out of the sqlite3_exec call like this: string sqlStatement = "CREATE TABLE people(id INT PRIMARY KEY NOT NULL, surname TEXT NOT NULL);"; result = sqlite3_exec(db, sqlStatement, &aCallback, null, &msg); ...it won't compile: Error: function etc.c.sqlite3.sqlite3_exec (sqlite3*, const(char)* sql,... is not callable using argument types (sqlite3*, string,... I can assign using: const char *sqlStatement = "CREATE TABLE... So how do I get a constant character pointer that can be modified at runtime? Paul
Jan 25 2015
On Sunday, 25 January 2015 at 18:15:21 UTC, Paul wrote:I'd like to vary the query based on input but if I try to move the string out of the sqlite3_exec call like this: string sqlStatement = "CREATE TABLE people(id INT PRIMARY KEY NOT NULL, surname TEXT NOT NULL);"; result = sqlite3_exec(db, sqlStatement, &aCallback, null, &msg); ...it won't compile: Error: function etc.c.sqlite3.sqlite3_exec (sqlite3*, const(char)* sql,... is not callable using argument types (sqlite3*, string,... I can assign using: const char *sqlStatement = "CREATE TABLE... So how do I get a constant character pointer that can be modified at runtime? PaulOnly string literals convert to const(char)*, because only for them it is guaranteed that they are null terminated. For everything else use toStringz.
Jan 25 2015
On Sunday, 25 January 2015 at 18:19:47 UTC, Tobias Pankrath wrote:Only string literals convert to const(char)*, because only for them it is guaranteed that they are null terminated. For everything else use toStringz.So, as a trivial example, is this how it's done?: string semiC = ";"; const char *sqlStatement = toStringz("CREATE TABLE people(id INT PRIMARY KEY NOT NULL, surname TEXT NOT NULL)"~semiC); Seems rather ugly but I guess it's a result of interfacing with C...
Jan 25 2015