In the following way, I am creating a table :
rc = sqlite3_exec(db, "create table demo (name text, age integer);", NULL, NULL, &zErrMsg);
if (rc != SQLITE_OK)
{
printf("Error: %s:Unable to create the table\n", zErrMsg);
}
Output:
Table: name age
I want to create a table dynamically with the different names & age:
Example:
Table: John 20
Is it possible to create it dynamically?
Requirement :
We want to create a table with column name that can be changed dynamically i.e
from our application we will get a name and we want to create a column in my table with that name.
We are facing data type conflict.
Example :
From our application we will get a character array :
char a[5] = "John".
We need to create a column with John as column name.
Thanks in advance
Related
I have created a student table in .cpp.
static const char student[] = R"sql(
CREATE TABLE if not exists student(
id VARCHAR(44) NOT NULL,
name varchar NOT NULL,
);
)sql";
I am adding some data in this table from another class. I know data has been added to this table, but I want to print all value from this table for verification.
then I write this statement,
static const char print_student[]="select * from student";
how can I print student table' data in CPP? I am using sqlite3 db.
I use sqlite on a c++ project, but I have a problem when i use WHERE on a column with TEXT values
I created a sqlite database:
CREATE TABLE User( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(24))
When i try to get the value of the column with VARCHAR values, it doesn't work, and return me a STATUS_CODE 101 just after the sqlite3_step :
int res = 0;
sqlite3_stmt *request;
char *sqlSelection = (char *)"SELECT * FROM User WHERE name='bob' ";
int id = 0;
res = sqlite3_prepare_v2(db, sqlSelection, strlen(sqlSelection), &request, NULL);
if (!res){
while (res == SQLITE_OK || res == SQLITE_ROW){
res = sqlite3_step(request);
if (res == SQLITE_OK || res == SQLITE_ROW ){
id = sqlite3_column_int(request, 0);
printf("User exist %i \n",id);
}
}
sqlite3_finalize(request);
I also tried with LIKE but it also doesn't work
SELECT * FROM User WHERE name LIKE '%bob%'
But when I execute the same code but for an INTERGER value
SELECT * FROM User WHERE id=1
It work fine.
In DB Browser for SQLite all requests work fine.
To solve the problem I searched what status code 101 means.
Here is what they said.
(101) SQLITE_DONE
The SQLITE_DONE result code indicates that an operation has completed.
The SQLITE_DONE result code is most commonly seen as a return value
from sqlite3_step() indicating that the SQL statement has run to
completion. But SQLITE_DONE can also be returned by other multi-step
interfaces such as sqlite3_backup_step().
https://sqlite.org/rescode.html
So, you're getting 101 because there is no more result from SELECT SQL.
The solution was to replace the VARCHAR fields by TEXT.
SQLite for c++ seems to don't manage VARCHAR fields when they are used after the WHERE
Trying to update table by user specified values. But the values are not getting updated.
cout<<"\nEnter Ac No"<<endl;
cin>>ac;
cout<<"\nEnter Amount"<<endl;
cin>>amt;
/* Create merged SQL statement */
sql = "UPDATE RECORDS set BAL = '%d' where ACCOUNT_NO = '%d'",amt, ac;
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
If I replace BAL and ACCOUNT_NO by some integer value instead of place holder then it is working fine.
Your sql string is not being created properly.
If you expect this code
sql = "UPDATE RECORDS set BAL = '%d' where ACCOUNT_NO = '%d'",amt, ac;
to result in
"UPDATE RECORDS set BAL = '1' where ACCOUNT_NO = '2'"
where
amt= 1 and ac = 2 then you need to use a string formatting call like this.
// the buffer where your sql statement will live
char sql[1024];
// write the SQL statment with values into the buffer
_snprintf(sql,sizeof(sql)-1, "UPDATE RECORDS set BAL = '%d' where ACCOUNT_NO = '%d'",amt, ac);
buff[sizeof(sql)-1]='\0';
On your particular platform _snprintf(...) might be snprintf(..) or another similarly named function. Also your compiler may warn about buffer manipulation security vulnerabilities. Choose the appropriate substitute for your needs
I am not able to get idea about the following requirement. The example table follows.
CREATE TABLE `test` (
`Id` INT NOT NULL,
`Name` VARCHAR(45) NULL,
`did_fk` INT NULL,
`adid_fk` INT NULL,
PRIMARY KEY (`Id`));
INSERT INTO test (id,name,did_fk,adid_fk)
VALUES
(1,'Rajesh',1,1),
(2,'Neeli',2,2),
(3,'Satish',3,3),
(4,'Ganesh',4,5),
(5,'Murali',9,10);
Here I need to compare the "id" with _fk columns i.e. did_fk & adid_fk. The "id" should be equal to did_fk & as well as adid_fk. If any of them is not true, then I should get that row.Here I need to get the rows 4 & 5.Since "_fk" columns are not equal to "id" value.Problem is "_fk" columns are not fixed. But "id" name is fixed.
SELECT * FROM `test` WHERE `Id` != `did_fk` OR `Id` != `adid_fk`
If your dynamic columns ends with _fk or some another suffix you can try to create SP like following
CREATE DEFINER=`root`#`localhost` PROCEDURE `GetNonEqualFkValues`(IN tableName varchar(255))
BEGIN
DECLARE c_name VARCHAR(255);
DECLARE done INT DEFAULT FALSE;
DECLARE curs CURSOR FOR select column_name from information_schema.columns where column_name like '%_fk';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN curs;
SET #q = concat("SELECT * FROM ", tableName, " WHERE 1!=1 ");
get_col: LOOP
FETCH curs INTO c_name;
IF done THEN
LEAVE get_col;
END IF;
SET #q = CONCAT(#q, " OR ", c_name," != id");
END LOOP get_col;
PREPARE stmt1 FROM #q;
EXECUTE stmt1;
END
And then invoke for concrete table like
call GetNonEqualFkValues('test')
The code isn't perfect, but it works for me and I think idea should be clear.
I create "database.db" and everything goes ok but why wouldn't it delete the table at the end? Everytime i run it, i get "table already exist" error message on creating the table.
int main()
{
sqlite3 *db; //Database Handle
char *zErr;
int rc;
char *sql;
rc = sqlite3_open("database.db", &db);
if(rc)
{
cout << "Can't open database: " << sqlite3_errmsg(db) << endl;;
sqlite3_close(db);
exit(1);
}
sql = "create table test(PID int primary key, Name text)"; //sql query
rc = sqlite3_exec(db, sql, NULL, NULL, &zErr); //execute sql statement
if(rc != SQLITE_OK)
{
if (zErr != NULL)
{
cout << "SQL error: " << zErr << endl;
sqlite3_free(zErr);
}
}
else
{
sql = "insert into test values (1,'John')";
rc = sqlite3_exec(db, sql, NULL, NULL, &zErr);
sql = "insert into test values (2,'Smith')";
rc = sqlite3_exec(db, sql, NULL, NULL, &zErr);
}
//delete the table on exit.
rc = sqlite3_exec(db, "delete from test", NULL, NULL, &zErr);
sqlite3_close(db);
return 0;
}
Also, can the primary keys be auto-generated following the last greater key existing in database?
You need to use drop table. delete deletes rows in the table.
rc = sqlite3_exec(db, "drop table test", NULL, NULL, &zErr);
SQLite will auto-increment an integer field declared as the primary key. See here.
You use a DELETE command to delete rows of a table.
You use a DROP command to drop a whole table or other DB item.
To create the table you can also use CREATE TABLE IF NOT EXISTS if you aren't sure if it exists.
To get your auto generated row ids use: id INTEGER PRIMARY KEY in your CREATE TABLE command.
Use DROP TABLE.
From SQLite docs:
The usual algorithm is to give the newly created row a ROWID that is one larger than the largest ROWID in the table prior to the insert.
The DML "delete from test" does delete all the rows from the table test. If you wish to drop the table, try "delete table test" or "drop table" instead.