Insert float value into table with C - c

I'm trying to insert a float value into my table "measurements" in column "thera0"
Can someone help me?
I'm beginner, don't be too hard :D
This is my first try error code
passing argument 5 of ‘PQexecParams’ from incompatible pointer type [-Wincompatible-pointer-types]
PGresult *res_values = PQexecParams(conn, "INSERT INTO measurements(theta0) VALUES($1)",1,NULL,buffer_theta0,NULL,NULL,0);
char*
expected ‘const char * const*’ but argument is of type ‘char *’
const char *const *paramValues,
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
And this is my second try error code
memory access error
float theta = 0.2;
char buffer_theta0[10];
sprintf(buffer_theta0,"%f",theta);
PGresult *res_values = PQexecParams(conn, "INSERT INTO measurements(theta0) VALUES($1)",1,NULL,buffer_theta0,NULL,NULL,0);
float theta = 0.2;
char buffer_theta0[10];
sprintf(buffer_theta0,"%f",theta);
const char * const paran[]= {buffer_theta0};
PGresult *res_values = PQexecParams(conn, "INSERT INTO measurements(theta0) VALUES($1)",1,NULL,paran,NULL,NULL,0);

Maybe this can help, more information is needed to reproduce the problem.
See comments inline for explanations.
Good luck!
See this discussion of how to use C to program prepared statements
The PQexecParams function creates a prepared statement and executes it. The second parameter is the SQL statement. The third parameter is the number of parameters passed. Passing NULL to the fourth parameter means that the server should figure out the parameter types. The fifth parameter is a pointer to an array of strings containing parameters. The next two parameters are only relevant with binary parameters. Passing 0 to the final parameter we obtain result in text format, 1 in binary format.
gcc -I /usr/local/opt/libpq/include main.c -L /usr/local/opt/libpq/lib -lpq
./a.out
1 'Audi' 52642 0.52642
2 'Mercedes' 57127 0.57127
3 'Skoda' 9000 0.9
4 'Volvo' 29000 0.29
5 'Bentley' 350000 0.35
6 'Citroen' 21000 0.21
7 'Hummer' 41400 0.414
8 'Volkswagen' 21600 0.216
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
void do_exit(PGconn *conn, PGresult *res) {
fprintf(stderr, "%s\n", PQerrorMessage(conn));
PQclear(res);
PQfinish(conn);
exit(1);
}
int main() {
// Data structure to hold the data going into the database
// using a variety of incoming data types, text, integer, and float
struct rawdata {
char* name;
int value;
float megaValue;
};
// These are the values to be inserted into the measurements table
struct rawdata rawtable [] =
{
{ "Audi" , 52642 , 0.52642 },
{ "Mercedes" , 57127 , 0.57127 },
{ "Skoda" , 9000 , 0.9 },
{ "Volvo" , 29000 , 0.29 },
{ "Bentley" , 350000 , 0.35 },
{ "Citroen" , 21000 , 0.21 },
{ "Hummer" , 41400 , 0.414 },
{ "Volkswagen" , 21600 , 0.216 }
};
// Here is the database connection being used
PGconn *conn = PQconnectdb("user=atl dbname=nameofdatabase");
if (PQstatus(conn) == CONNECTION_BAD) {
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
PQfinish(conn);
exit(1);
}
// To be more helpful to others, create the table in each example
// this allows everyone to see the table format and how it was created
// sometimes the error is in the way tables are created
PGresult *res = PQexec(conn, "DROP TABLE IF EXISTS measurements");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { do_exit(conn, res); }
PQclear(res);
res = PQexec(conn, "CREATE TABLE measurements ( measure_id serial PRIMARY KEY, col1 text, col2 integer, col3 float );" );
if (PQresultStatus(res) != PGRES_COMMAND_OK) { do_exit(conn, res); }
PQclear(res);
// This is related to the ask about how to insert values into a table using PQexecParams
// This is the string that specifies the command and the params
char *sinto = "INSERT INTO measurements VALUES($1,$2,$3,$4)";
// This is the loop to change the params on each row (and provide a unique ID)
for(int i=0; i<sizeof(rawtable) / sizeof(rawtable[0]); i++)
{
// creating storage for params, not the best way (works though)
char p1[100], p2[100], p3[100], p4[100];
// prepare param input array by initializing array to params
const char *paramValues[] = { p1, p2, p3, p4 };
// initialize params for this iteration
sprintf( p1, "%d", i+1 ); // key
sprintf( p2, "'%s'", rawtable[i].name ); // text
sprintf( p3, "%d", rawtable[i].value ); // integer
sprintf( p4, "%0.6f", rawtable[i].megaValue ); // float
// make call to database server
res = PQexecParams(conn, sinto, 4, NULL, paramValues, NULL, NULL, 0);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
do_exit(conn, res);
PQclear(res);
}
// display results
res = PQexec(conn, "SELECT * FROM measurements");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
printf("No data retrieved\n");
PQclear(res);
do_exit(conn, res);
}
int rows = PQntuples(res);
for(int i=0; i<rows; i++) {
printf("%s %s %s %s\n", PQgetvalue(res, i, 0), PQgetvalue(res, i, 1), PQgetvalue(res, i, 2), PQgetvalue(res, i, 3));
}
PQclear(res);
PQfinish(conn);
return 0;
}

Related

Printing SQL in C

I'm looking for help with printing the results of an SQL statement out in C. I'm trying not to set each variable to a pointer and then using that pointer to print the variable out. If I did, I'd have like a couple hundred variables. This is what I've tried so far. I'm literally lost on how to get this to output correctly. Any help would be appreciated.
int hstmt = DBActivateSQL(hdbc, "SELECT * FROM REG_RESULTSTABLE");
if (hstmt <= 0)
{
ShowError();
}
sprintf(uutNum, "%s \n", hstmt);
while((resCode = DBFetchNext(hstmt)) == DB_SUCCESS) {
SetCtrlVal(panelHandle, PANEL_lstregulator, uutNum);
}
Prototype of DBActivateSQL is
int DBActivateSQL (int connectionHandle, char SQLStatement[]);
It is returns int.
Hence hstmt should be declared as int type.
int hstmt = DBActivateSQL(hdbc, "SELECT * FROM REG_RESULTSTABLE");
To print it to string you need use %d not %s as hsmt is of type int.
sprintf(uutNum, "%d",hstmt);
^^------------------------//Using %d instead of %s here
The functions that you want are DBFetchNext and DBGetCol* (DBGetColChar, DBGetColDouble, ...). According to the documentation page on DBGetColChar, the flow should be something like this, where you only need one variable per column:
void print_MyTable(int hdbc)
{
char *var1;
int var2;
float var3;
int statement = DBActivateSQL(hdbc, "SELECT col1, col2, col3 FROM MyTable");
int resultCode;
while ((resultCode = DBFetchNext(statement)) == DB_SUCCESS) {
if ((resultCode = DBGetColChar(statement, 1, &var1, "")) != DB_SUCCESS) {
// Handle the error
break;
}
if ((resultCode = DBGetColInt(statement, 2, &var2)) != DB_SUCCESS) {
// Handle the error
DBFree(var1);
break;
}
if ((resultCode = DBGetColFloat(statement, 3, &var3)) != DB_SUCCESS) {
// Handle the error
DBFree(var1);
break;
}
// Print the values
printf("col1: %s, col2: %d, col3: %f\n", var1, var2, var3);
// Free the string's memory
DBFree(var1);
}
statement = DBDeactivateSQL(statement);
}

Delete the record using libpq PQexecParams() query

I am trying to delete a record using libpq PQexecParams() function. The query is successfully returned but required row is not deleted from the table. Here is the snippet from my code for reference. I have used PQexecParams() for select and insert successfully. Could you please help, what am I missing!
PGresult *res;
int meter_info_id;
printf ("Enter Meter Information Id");
scanf("%d", &meter_info_id);
char *stm_write_reg = "delete from write_reg_set where meter_id=$1";
int nparam = 1;
//set the values to use
const char *values[1] = {(char *)&meter_info_id};
//calculate the lengths of each of the values
int lengths[1] = {sizeof(meter_info_id)};
//state which parameters are binary
int binary[1] = {1};
res = PQexecParams(conn,
stm_write_reg,
nparam, //number of parameters
NULL, //ignore the Oid field
values, //values to substitute $1 and $2 and so on
lengths, //the lengths, in bytes, of each of the parameter values
binary, //whether the values are binary or not
0); //we want the result in text format
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "stm_write_reg failed: %s", PQerrorMessage(conn));
exit_nicely(conn,res);
}
PQclear(res);
I have found the problem.
I was missing
meter_info_id = htonl(meter_info_id);
By adding it, fixed the problem.

SQLite in C. sqlite3_exec: parameter set in callback function prints incomplete data when called in main()

I am trying to achieve something very basic. But unfortunately I am unable to get the expected result.
I have a sqlite table named emp_infohaving 9 employee records in following fields:
SR_NO[0], NAME[1], AGE[2], SEX[3], ADDRESS[4], EMPID[5], CARDID[6] and SALARY[7].
To access the table and fetch the employee record as per sql query, I have following program in C:
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>
static int callback(void *param, int argc, char *argv[], char **azColName){
int i=0;
if(argc == 0) return 0;
char **res = (char **)param;
*res = (char *)realloc(*res, sizeof(*res));
//for(i=0; i<argc; i++){
//printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
strcpy(*res, argv[1], sizeof(*res));
printf("%s\n", *res);
// }
return 0;
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
char *param;
rc = sqlite3_open("/DBsqlite3/foreign_key.db", &db);
if( rc )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}
else
{
fprintf(stderr, "\nOpened database successfully\n\n");
}
sql="select * from emp_info;"
rc = sqlite3_exec(db, sql, callback, &param, &zErrMsg);
if( rc != SQLITE_OK )
{
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
else
{
fprintf(stdout, "Operation done successfully\n\n");
printf("the value of data is %s \n\n", param);
}
free(param);
sqlite3_close(db);
return 0;
}
The output is as follows:
`
Opened database successfully
AAA
BBB
CCC
DDD
EEE
FFF
GGG
HHH
III
Operation done successfully
the value of data is III
I expected that all the AAA,BBB,CCC,.... will get stored in param and will get printed. But that's not happening. param takes only the last record only.
Why is this happening ? I suspect strcpy() is creating the problem.
Kindly help.
Apart from this, my real aim is to get all the valid employee record (as per sql query) to get stored in param and it should display all the fields(SR_NO[0], NAME[1], AGE[2], SEX[3], ADDRESS[4], EMPID[5], CARDID[6] and SALARY[7]). say for example if i provide following query to sql
sql="SELECT * FROM emp_info WHERE AGE>40";
then the param should display result as follow
7 GGG 41 MALE G1G2G3G4 307 7777GGG 77777
8 HHH 42 FEMALE H1H2H3H4 308 8888HHH 88888
9 III 43 FEMALE I1I2I3I4 309 9999IIII 99999
And not just a column.How can I achieve this ?
Thank you in advance.
working on the suggestions suggested by CL. I started working on writing the code on cursor-based API. And I got the desired output.
#include <iostream>
#include <sqlite3.h>
#include <stdlib.h>
#include <list>
#include <iterator>
#include <algorithm>
using namespace std;
class sqliteDB
{
private:
int rc;
sqlite3 *db;
char *zErrMsg;
const char *sql;
sqlite3_stmt * stmt;
list<string> answer;
public:
//================================XX=====================================//
bool connectDB()
{
rc = sqlite3_open("/DBsqlite3/foreign_key.db", &db);
if( rc )
{
cerr << "Can't open database: " << sqlite3_errmsg(db) << endl;
sqlite3_close(db);
exit(1);
}
else
{
std::cout<<"\n\nDatabase opened successfully\n\n";
}
}
//===============================XX=====================================//
void allEmp()
{
int AGE;
//Preparing the statement
rc=sqlite3_prepare(db,"SELECT * FROM emp_info WHERE AGE>40;", -1, &stmt, NULL );
if (rc != SQLITE_OK){
throw string(sqlite3_errmsg(db));
}
else{
cout<<"\n\nThe statement was prepared successfully\n\n";
}
// Creating List Container //
cout << "\n\nList answer was created successfully\n\n";
while(sqlite3_step(stmt) == SQLITE_ROW) {
cout << "Rows" << endl;
int column = sqlite3_column_count(stmt);
for(int i = 0; i < column; i++)
{
cout << "Columns" << endl;
answer.push_back(string((const char *) sqlite3_column_text(stmt, i)));
}
}
sqlite3_finalize(stmt);
cout << "\n\nDatabase was closed successfully\n\n";
}
//==============================XX=====================================//
void printList(){
int s = answer.size();
for( list<std::string>::const_iterator it = answer.begin(); it != answer.end(); it++)
cout << it->c_str() << endl;
}
//===================================XX===============================//
};
int main()
{
sqliteDB object1;
object1.connectDB();
object1.allEmp();
object1.printList();
cout << "\n\nAll the statement were executed properly\n\n";
return 0;
}
//========================END OF CODE===========================//
The Output is as follows
Database opened successfully
The statement was prepared successfully
List answer was created successfully
Rows
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Rows
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Rows
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Columns
Database was closed successfully
7
GGG
41
MALE
G1G2G3G4
307
7777GGG
77777
9833446677
abi#gmail.com
07:08:1947
NONE
8
HHH
42
FEMALE
H1H2H3H4
308
8888HHH
88888
9833446688
abj#gmail.com
08:09:1947
NONE
9
III
43
FEMALE
I1I2I3I4
309
9999IIII
99999
9833446699
abk#gmail.com
09:10:1947
NONE
All the statement were executed properly
The major problem I faced was with the overloading of "<<" operator.
Thank you CL.
I'm no expert in this, but a simple google search shows, the syntax of sqlite3_exec() is
int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
Note the 4th parameter, it is suppossed to be a void *.
As per your definition of variables and calling convention,
char *param;
and
rc = sqlite3_exec(db, sql, callback, &param, &zErrMsg);
you're getting the 4th param wrong. You may want to rewrite it as
rc = sqlite3_exec(db, sql, callback, (void *)param, &zErrMsg);
Note: [If not being taken care already by sqlite3_exec()] You may need to allocate memory to param before being passed to sqlite3_exec(). Also, instead of directly passing argv to the callback, you may want to have some sanity and validity check of the same.
You took the code from an answer where the goal was to read a single result row.
The strcpy overwrites the previous value of the same variable.
You should use the cursor-based API, and call sqlite3_step in a loop:
...
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
my_object *o = new ...;
o->set_field(sqlite3_column_xxx(stmt, 1);
...
my_list.add(o);
}
...

C SQLite Inserts BLOB instead of String and Vice Versa When Binding Parameters

So I'm having some trouble with parameter binding with SQLite in C. I am using sqlite3_bind_* functions to insert BLOBs and strings into a database. After an insertion however, I inspect the database with SQLiteBrowser and find to my surprise that the types are all jumbled up! Here is some sample code that should reproduce the effect.
This chunk creates the table.
const char *TABLE_NAME = "PASSWORD_ENTRY";
const char *USER_ID_COLUMN_NAME = "USER_ID";
const char *INDEX_COLUMN_NAME = "INDEX_VALUE";
const char *SERVICE_COLUMN_NAME = "SERVICE";
const char *SYM_ENC_KEY_COLUMN_NAME = "SYM_ENC_KEY";
const char *ASYM_ENC_KEY_COLUMN_NAME = "ASYM_ENC_KEY";
const char *TIMESTAMP_COLUMN_NAME = "TIMESTAMP";
/* CREATE TABLE IF NOT EXISTS TABLE_NAME (
USER_ID_COLUMN_NAME INTEGER,
INDEX_COLUMN_NAME INTEGER,
SERVICE_COLUMN_NAME TEXT,
SYM_ENC_KEY_COLUMN_NAME BLOB,
ASYM_ENC_KEY_COLUMN_NAME BLOB,
TIME_STAMP_COLUMN_NAME BLOB,
PRIMARY KEY (USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME));
*/
char *f = "CREATE TABLE IF NOT EXISTS %s (%s INTEGER, %s INTEGER, %s TEXT, %s BLOB, %s BLOB, %s BLOB, PRIMARY KEY (%s, %s));";
char *s = malloc(snprintf(NULL, 0, f, TABLE_NAME, USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME, SERVICE_COLUMN_NAME, SYM_ENC_KEY_COLUMN_NAME, ASYM_ENC_KEY_COLUMN_NAME, TIMESTAMP_COLUMN_NAME, USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME) + 1);
sprintf(s, f, TABLE_NAME, USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME, SERVICE_COLUMN_NAME, SYM_ENC_KEY_COLUMN_NAME, ASYM_ENC_KEY_COLUMN_NAME, TIMESTAMP_COLUMN_NAME, USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME);
const char *DB_NAME = "passwordmanager.db";
sqlite3* db;
int r = 0;
// Get the database
r = sqlite3_open(DB_NAME, &db);
if (r) {
printf("Error opening database: %s\n", sqlite3_errmsg(db));
return NULL;
}
printf("Database opened.\n");
r = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL);
if (r) {
printf("Error preparing create table statement: %s\n", sqlite3_errmsg(db));
return 1;
}
r = sqlite3_step(stmt);
if (r != 101 && r) {
printf("Error executing create table statement: %s\n", sqlite3_errmsg(db));
return 1;
}
printf("Password entry table ready.\n");
sqlite3_finalize(stmt);
Now that that's done, I'll give you a sample insertion.
sqlite3_stmt *stmt2;
long userId = 50l;
short index = 2;
long timestamp = 100l;
char *service = "stackoverflow.com";
const int SYM_ENC_KEY_LEN = 10;
const int ASYM_ENC_KEY_LEN = 11;
char *symEncKey = "symEncKey";
char *asymEncKey = "asymEncKey";
char *f = "INSERT INTO PASSWORD_ENTRY (USER_ID, INDEX_VALUE, SERVICE, TIMESTAMP, SYM_ENC_KEY, ASYM_ENC_KEY) VALUES (?, ?, ?, ?, ?, ?);";
printf("SQL ready.\n");
r = sqlite3_prepare_v2(db, f, strlen(f), &stmt2, NULL);
if (r != 0) {
printf("Error preparing addition statement: %s\n", sqlite3_errmsg(db));
sqlite3_finalize(stmt2);
sqlite3_close(db);
return;
}
printf("Prepared the addition statement, binding...\n");
sqlite3_bind_int64(stmt2, 1, (sqlite3_int64) userId);
sqlite3_bind_int(stmt2, 2, (int) index);
sqlite3_bind_text(stmt2, 3, service, strlen(service) + 1, 0);
sqlite3_bind_int64(stmt2, 4, (sqlite_int64) timestamp);
sqlite3_bind_blob(stmt2, 5, (void *) symEncKey, SYM_ENC_KEY_LEN, 0);
sqlite3_bind_blob(stmt2, 6, (void *) asymEncKey, ASYM_ENC_KEY_LEN, 0);
// Execute the statement
r = sqlite3_step(stmt2);
if (r != 101) {
printf("Error executing addition statement: %s\n", sqlite3_errmsg(db));
sqlite3_finalize(stmt2);
sqlite3_close(db);
return;
}
printf("Executed the addition statement.\n");
sqlite3_finalize(stmt2);
sqlite3_close(db);
Now, if you'd care to view the database with SQLiteBrowser or any similar tool you may have, provided you have the same luck as me, you'll see that column SERVICE contains a BLOB and the SYM_ENC_KEY column contains a string, regardless of the fact that I used the opposite sqlite3_bind_* functions. Does anyone have any idea as to how this could be happening? If you need more information, please ask. I am a new poster.
sqlite3_bind_text(stmt2, 3, service, strlen(service) + 1, 0);
The zero terminator is not considered part of the string's data.
Remove the + 1, or better, just give -1.
The last parameter is wrong; you must provide a destructor function, or SQLITE_TRANSIENT or SQLITE_STATIC.
(The _blob calls have the same problems.)
However, the output of the .dump command in the command-line shell contains this:
INSERT INTO "PASSWORD_ENTRY" VALUES(50,2,'stackoverflow.com',X'73796D456E634B657900',X'6173796D456E634B657900',100);
This is correct. There is no data type problem.

sqlite3_bind_text on select, different result on prepared vs string SQL statement

I have a problem with the sqlite3_bind_text function when I try to use it for select.
The intention is to get the newest value in a 10 min time slot of my data.
If I use a prepared statement and bind my value the result is different compared to a normal string with SQL syntax.
The SQL syntax of the two tests 'should' be the same.
When the code runs I get the following output:
test 1 = 0.000000 AnalogRPM <-- Error
test 2 = 7.700000 7.69999980926514 <-- Correct value
It seems to me that my bound statement returns the name of the column instead of the value (as if the value is inserted as 'AnalogRPM'
Has anyone of you experienced anything similar? or can you see any faults in my code?
Any feedback is appreciated :)
char str[1000];
sqlite3_stmt *test1;
/** First test, use prepared statement to get double value */
snprintf(str, sizeof(str),
"select ? from DATA WHERE ts_sec BETWEEN ? AND ? ORDER BY rowid DESC LIMIT 1");
/** All 'rc' are check in my code, i just left them out to make it easier to read */
rc = sqlite3_prepare_v2(db_livedata, str, -1, &test1, 0);
if(rc != SQLITE_OK)
printf("SQL error on line:%d msg:%s \n",__LINE__, sqlite3_errmsg(db_livedata));
rc = sqlite3_bind_text( test1, 1, "AnalogRPM",-1,0);
rc = sqlite3_bind_int( test1, 2, stat_time.tv_sec - 600);
rc = sqlite3_bind_int( test1, 3, stat_time.tv_sec);
do
{
rc = sqlite3_step( test1);
switch( rc )
{
/** No more data */
case SQLITE_DONE:
break;
/** New data */
case SQLITE_ROW:
{
uint16_t size = sqlite3_column_count( test1);
if(size == 1) // should always be one
{
value = sqlite3_column_double( test1, 0);
printf("test 1 = %f %s\n",value, sqlite3_column_text(test1, 0));
}
}
break;
default:
break;
}
}while( rc==SQLITE_ROW );
/** Second test use normal string for prepare */
sqlite3_stmt *test2;
snprintf(str, sizeof(str),
"select AnalogRPM from DATA WHERE ts_sec BETWEEN %d AND %d ORDER BY rowid DESC LIMIT 1"
,stat_time.tv_sec - 600, stat_time.tv_sec);
rc = sqlite3_prepare_v2(db_livedata, str, -1, &test2, 0);
if(rc != SQLITE_OK)
printf("SQL error on line:%d msg:%s \n",__LINE__, sqlite3_errmsg(db_livedata));
do
{
rc = sqlite3_step( test2);
switch( rc )
{
/** No more data */
case SQLITE_DONE:
break;
/** New data */
case SQLITE_ROW:
{
uint16_t size = sqlite3_column_count( test2);
if(size == 1)
{
value = sqlite3_column_double( test2, 0);
printf("test 2 = %f %s\n",value, sqlite3_column_text(test2, 0));
}
}
break;
default:
break;
}
}while( rc==SQLITE_ROW );
First version is essentially
SELECT 'AnalogRPM' ...
while the second is
SELECT AnalogRPM ...
The difference is the expression being either a string literal or a column name.
You cannot use variable binding for column names. Column names need to be known at SQL statement compile time.

Resources