Adding a time stamp to SQLite table in C - c
I am attempting to migrate some code from python to C. Everything is going well except adding a timestamp to the SQlite3 table.
Here is the working Python code.
cur.execute("CREATE TABLE IF NOT EXISTS PLCValues(ID INTEGER PRIMARY KEY AUTOINCREMENT, [timestamp] timestamp, \
x001 NUMERIC, x002 NUMERIC, x003 NUMERIC, x004 NUMERIC, x005 NUMERIC, x006 NUMERIC, x007 NUMERIC, x008 NUMERIC,\
y001 NUMERIC, y002 NUMERIC, y003 NUMERIC, y004 NUMERIC, y005 NUMERIC, y006 NUMERIC,\
x201 NUMERIC, x202 NUMERIC, x203 NUMERIC, x204 NUMERIC, x205 NUMERIC, x206 NUMERIC, x207 NUMERIC, x208 NUMERIC,\
df1 REAL, df2 REAL, df3 REAL, df4 REAL)")
cur.execute("INSERT INTO PLCValues VALUES(null, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",\
(datetime.now(), \
regs1[0], regs1[1], regs1[2], regs1[3], regs1[4], regs1[5], regs1[6], regs1[7],\
regs2[0], regs2[1], regs2[2], regs2[3], regs2[4], regs2[5],\
regs3[0], regs3[1], regs3[2], regs3[3], regs3[4], regs3[5], regs3[6], regs3[7],\
Temp/10, Humid/10, 0, 0))
In C, I had to change things a little. my date code is 2019-02-10 21:42:06 which is a approved format.
sql = "CREATE TABLE IF NOT EXISTS PLCValues(ID INTEGER PRIMARY KEY AUTOINCREMENT, TEXT DEFAULT CURRENT_TIMESTAMP, \
x001 NUMERIC, x002 NUMERIC, x003 NUMERIC, x004 NUMERIC, x005 NUMERIC, x006 NUMERIC, x007 NUMERIC, x008 NUMERIC,\
x201 NUMERIC, x202 NUMERIC, x203 NUMERIC, x204 NUMERIC, x205 NUMERIC, x206 NUMERIC, x207 NUMERIC, x208 NUMERIC,\
y001 NUMERIC, y002 NUMERIC, y003 NUMERIC, y004 NUMERIC, y005 NUMERIC, y006 NUMERIC,\
df1 REAL, df2 REAL, df3 REAL, df4 REAL)";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
strftime(TimeStamp, 20, "%Y-%m-%d %H:%M:%S", localtime(&now));
snprintf(sql, sizeof(sql), \
"INSERT INTO PLCValues VALUES(%s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %f, %f, %f, %f)", \
TimeStamp, p.regs1[0], p.regs1[1], p.regs1[2], p.regs1[3], p.regs1[4], p.regs1[5], p.regs1[6], p.regs1[7],\
p.regs2[0], p.regs2[1], p.regs2[2], p.regs2[3], p.regs2[4], p.regs2[5], p.regs2[6], p.regs2[7],\
p.regs3[0], p.regs3[1], p.regs3[2], p.regs3[3], p.regs3[4], p.regs3[5], p.Temp, p.Humid, 0, 0);
int rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
When I run it, it gets hung up on the time string space
SQL error: near "21": syntax error
I have tried changing things around, but have limited experience with SQLite
Thanks for any help!
Here is the code used to get this working. including the timestamp!
char *err_msg = 0;
sqlite3_stmt *res;
//pull current time
char TimeStamp[20];
time_t now = time(NULL);
strftime(TimeStamp, 20, "%Y-%m-%d %H:%M:%S", localtime(&now));
printf("%s\n",TimeStamp);
char *sql = "INSERT INTO PLCValues VALUES(null, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
int rc = sqlite3_prepare_v2(db, sql, -1, &res, 0);
if (rc == SQLITE_OK ) {
//Bind the variables
sqlite3_bind_text(res, 1, TimeStamp, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(res, 2, p.regs1[0]);
sqlite3_bind_int(res, 3, p.regs1[1]);
sqlite3_bind_int(res, 4, p.regs1[2]);
sqlite3_bind_int(res, 5, p.regs1[3]);
sqlite3_bind_int(res, 6, p.regs1[4]);
sqlite3_bind_int(res, 7, p.regs1[5]);
sqlite3_bind_int(res, 8, p.regs1[6]);
sqlite3_bind_int(res, 9, p.regs1[7]);
sqlite3_bind_int(res, 10, p.regs2[0]);
sqlite3_bind_int(res, 11, p.regs2[1]);
sqlite3_bind_int(res, 12, p.regs2[2]);
sqlite3_bind_int(res, 13, p.regs2[3]);
sqlite3_bind_int(res, 14, p.regs2[4]);
sqlite3_bind_int(res, 15, p.regs2[5]);
sqlite3_bind_int(res, 16, p.regs3[0]);
sqlite3_bind_int(res, 17, p.regs3[1]);
sqlite3_bind_int(res, 18, p.regs3[2]);
sqlite3_bind_int(res, 19, p.regs3[3]);
sqlite3_bind_int(res, 20, p.regs3[4]);
sqlite3_bind_int(res, 21, p.regs3[5]);
sqlite3_bind_int(res, 22, p.regs3[6]);
sqlite3_bind_int(res, 23, p.regs3[7]);
sqlite3_bind_double(res, 24, p.Temp);
sqlite3_bind_double(res, 25, p.Humid);
sqlite3_bind_double(res, 26, 0);
sqlite3_bind_double(res, 27, 0);
}else{
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
return -1;
}
int step = sqlite3_step(res);
if (step == SQLITE_ROW) {
printf("%s: ", sqlite3_column_text(res, 0));
printf("%s\n", sqlite3_column_text(res, 1));
}
sqlite3_finalize(res);
}
Related
Always Encrypted - Parameters
Have set up Always Encrypted for my table columns at server side. From a C++ client, I use the below connection string to connect to the database: CString connString = L"Driver={ODBC Driver 17 for SQL Server};Server=192.122.200.200,1433;Encrypt=no;Trusted_Connection=no;ColumnEncryption=Enabled;DATABASE=AlwaysEncrypted;UID=sa;PWD=;"; From the same client I invoke below command to insert data: CString csQStrInsert = L"declare #val1 int = 3; declare #val2 int = 3; insert into [dbo].[Table_AlwaysEncrypted] ([col1], [col2]) values (#val1, #val2);"; pDatabase->ExecuteSQL(csQStrInsert); Unfortunately the query fails with below error: pEX->m_strError = L"Encryption scheme mismatch for columns/variables '#val1'. The encryption scheme for the columns/variables is (encryption_type = 'PLAINTEXT') and the expression near line '1' expects it to be DETERMINISTIC, or PLAIN TEXT. What am I doing wrong?
You cannot use local variables for Always Encrypted columns, they must come from client-side parameters. In SSMS it works because SSMS parses your script and pulls out the variables into parameters, but in C++ or other clients you must parameterize it yourself. For example, the below code is used as an example on Microsoft's website, see there for more info on how to use Always Encrypted: SQL_DATE_STRUCT date; SQLLEN cbdate; // size of date structure SQLCHAR SSN[12]; strcpy_s((char*)SSN, _countof(SSN), "795-73-9838"); SQLWCHAR* firstName = L"Catherine"; SQLWCHAR* lastName = L"Abel"; SQLINTEGER cbSSN = SQL_NTS, cbFirstName = SQL_NTS, cbLastName = SQL_NTS; // Initialize the date structure date.day = 10; date.month = 9; date.year = 1996; // Size of structures cbdate = sizeof(SQL_DATE_STRUCT); SQLRETURN rc = 0; string queryText = "INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES (?, ?, ?, ?) "; rc = SQLPrepare(hstmt, (SQLCHAR *)queryText.c_str(), SQL_NTS); //SSN rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 11, 0, (SQLPOINTER)SSN, 0, &cbSSN); //FirstName rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)firstName, 0, &cbFirstName); //LastName rc = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)lastName, 0, &cbLastName); //BirthDate rc = SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_TYPE_DATE, SQL_TYPE_DATE, 10, 0, (SQLPOINTER)&date, 0, &cbdate); rc = SQLExecute(hstmt); As you can see, SQLBindParameter is used to add parameters to the query. You cannot use either literals or SQL local variables to insert or compare with encrypted columns, as the server has no access to the decrypted data. The client driver needs to have access to the relevant certificate.
Sqlite3 insert data in database does not work in c
sqlite3_stmt *stmt; sqlite3_prepare_v2(db, "INSERT INTO links(NAME, LINK, SIZE, STARRED) VALUES ('?' , '?', ? , 0);", 41, &stmt, NULL); if(stmt != NULL) { sqlite3_bind_text(stmt, 1, name, 0, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 2, link, 0, SQLITE_TRANSIENT); sqlite3_bind_int(stmt, 3, size); sqlite3_step(stmt); sqlite3_finalize(stmt); }else{ printf("%sError during insertion in the database%s\n", RED, RST); } sqlite3_close(db); I always get on the output Error during insertion in the database but can't understand why, maybe something related to sqlite3_prepare_v2 but doesn't know what, I tried to execute the query 'manually' with random data and it works.
The size of the zSql statement is 69 characters. It is is better to us -1 for length as by default it will be null-terminated string and size is automatically computed : sqlite3_prepare_v2(db, "INSERT INTO links(NAME, LINK, SIZE, STARRED) VALUES (?, ?, ? , 0);", -1, &stmt, NULL); Do not forget the 3rd '?' in the statement for the 3rd argument. Edit : write it as ? in the statement
You bind twice item 2 of the statement and ? is missing for item 3.
Just solved by changing the third parameter of sqlite3_prepare_v2() that is the maximum length of zSql in bytes, and 47 is to small.
SQLite prepare method fails due to syntax error
So I want to create a database for Users and insert values into the fields using variable. Initially I tried using it calling the do function, but it wasn't reading the variables properly so I decided to just use prepare and execute separately. This is my code: $dbh->do("DROP TABLE IF EXISTS Users"); $dbh->do("CREATE TABLE Users( zid TEXT, Name TEXT, Email TEXT, password TEXT, Mates TEXT, Program TEXT, Courses TEXT, Suburb TEXT, Birthday TEXT)"); $zid = "z33432523"; $name = "John Doe"; $email = "email#gmail.com"; $password = "alien"; $mates = "z3459148 z3458291"; $program = ""; $courses = ""; $suburb = ""; $birthday = "13/5/1992"; $sth = $dbh->prepare('INSERT INTO Users VALUES (?, ?, ?, ?, ?. ?, ?, ?, ?)'); $sth->execute($zid, $name, $email, $password, $mates, $program, $courses, $suburb, $birthday); $dbh->disconnect(); However, if I try running this code I get the following error: DBD::SQLite::db prepare failed: near ".": syntax error at ./dbm.pl line 35. I'm not sure exactly what the problem is?
near ".": syntax error INSERT INTO Users VALUES (?, ?, ?, ?, ?. ?, ?, ?, ?) ^
getparameter return null jsp when get time like 9:00
PreparedStatement pstmt = conn .prepareStatement("INSERT INTO discussion(section_id, weekday, room, mandatory, starttime,endtime) VALUES ( ?, ?, ?, ?, ?, ?)"); pstmt.setInt(1, Integer.parseInt(request.getParameter("SECTION_ID"))); pstmt.setString(2, request.getParameter("WEEKDAY")); pstmt.setString(3, request.getParameter("ROOM")); pstmt.setString(4, request.getParameter("MANDATORY")); String TIME_FORMAT = "HH:mm"; SimpleDateFormat timeFormat = new SimpleDateFormat(TIME_FORMAT, Locale.getDefault()); out.println("Items: " + request.getParameter("starttime")); out.println("Items: " + request.getParameter("WEEKDAY")); pstmt.setTime(5, new Time(timeFormat.parse(request.getParameter("starttime")) .getTime())); pstmt.setTime(6, new Time(timeFormat.parse(request.getParameter("endtime")) .getTime())); pstmt.executeUpdate(); I use out.print to test. find out that getparameter works not right. It can give me the weekday data but cannot give me starttime data. The database give starttime time type
SQLAlchemy: Omit attribute in INSERT column list
How do I omit a table attribute from being included upon insertion? I have the following class: class PurchaseOrder(Base): __tablename__ = 'PPurchaseOrder' id = Column('PurchaseOrderId', Integer, Sequence('transactions_id_seq'), primary_key = True) code = Column(String(50)) ris_id = Column('RisId', Integer, ForeignKey('BRIS.RisId')) creator = Column('CreatedBy', String(256)) created = Column('CreateDate', DateTime) date_needed = Column('DateNeeded', DateTime) timestamp = Column('Timestamp', TIMESTAMP) supplier_items = AssociationProxy('purchase_order_items', 'supplier_item', creator='SupplierItem') purchase_order_items = relationship('PurchaseOrderItem', cascade="all, delete, delete-orphan", backref='purchase_order', lazy='joined') def __init__(self, code, created, date_needed): self.code = code self.creator = 'Marco' self.created = created self.date_needed = date_needed When trying to add an object, it does the following insert statement: 2011-06-30 22:37:26,953 INFO sqlalchemy.engine.base.Engine INSERT INTO [PPurchaseOrder] (code, [RisId], [CreatedBy], [CreateDate], [DateNeeded], [Timestamp]) OUTPUT inserted.[PurchaseOrderId] VALUES (?, ?, ?, ?, ?, ?) 2011-06-30 22:37:26,953 INFO sqlalchemy.engine.base.Engine ('POF000872008', None, 'Marco', datetime.datetime(2008, 5, 27, 8, 47, 18), datetime.datetime(2008, 5, 28, 15, 48), None) I want the Timestamp column out so that the insert statement would look like this: 2011-06-30 22:37:26,953 INFO sqlalchemy.engine.base.Engine INSERT INTO [PPurchaseOrder] (code, [RisId], [CreatedBy], [CreateDate], [DateNeeded]) OUTPUT inserted.[PurchaseOrderId] VALUES (?, ?, ?, ?, ?, ?) 2011-06-30 22:37:26,953 INFO sqlalchemy.engine.base.Engine ('POF000872008', None, 'Marco', datetime.datetime(2008, 5, 27, 8, 47, 18), datetime.datetime(2008, 5, 28, 15, 48))
IIRC, providing default or server_default argument will move the value generation to the server side. See here for more