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);
}
I have a function, lastday, that returns the last day of a given month. Code below...
Function lastday(dteAny As Date) As Date
lastday = DateSerial(Year(dteAny), Month(dteAny) + 1, 1) - 1
End Function
I am attempting to run a query you see below..
Select cc.cred_id, lastday(dateadd("m", 5, date())) as [due],
lastday(dateadd("m", 36, a.activity_date)) as [report]
from cred_core as cc
inner join activity as a on (a.cred_id = cc.cred_id and a.activity_type =
"recred sent" and lastday(dateadd("m", 5, date())) = lastday(dateadd("m",
36, a.activity_date)) )
I get an error alerting me of a data type mismatch on the second half of the join, where I use the lastday function.
I tried surrounding the lastday function with the # delimeters hoping that it would convert it to something it could actually compare, but I assume those delimeters don't work on functions?
Any idea what I can do to solve this problem? activity_date is, of course, a date/time data type. Using Access 2007-2013.
Those type of joins are not supported in Access. Try to set the dates in criteria.
SELECT cc.cred_id, lastday(DateAdd("m", 5, Date())) As [due],
lastday(DateAdd("m", 36, a.activity_date)) As [report]
FROM cred_core as cc INNER JOIN activity As a ON (a.cred_id = cc.cred_id)
WHERE a.activity_type = "recred sent"
AND lastday(DateAdd("m", 5, date())) = lastday(DateAdd("m", 36, a.activity_date));
I have bundle of delete queries like following :-
DELETE FROM [Entry]
WHERE CompanyId = 1
AND EmployeeId IN (3, 4, 6, 7, 14, 17, 20, 21, 22,....100 more)
AND Entry_Date = '2016-12-01'
AND Entry_Method = 'I'
SO in my code, i run this list of queries as below :-
using (var ctx = new ApplicationDbContext(schemaName))
{
foreach (var item in queries)
{
ctx.Database.ExecuteSqlCommand(item);
}
}
But due to the large number of queries executing it creates a lock on sql, so i decided to execute the queries in chunk, so i found the below code :-
SET ROWCOUNT 500
delete_more:
DELETE FROM [Entry]
WHERE CompanyId = 1
AND EmployeeId IN (3, 4, 6, 7, 14, 17, 20, 21, 22,....100 more)
AND Entry_Date = '2016-12-01'
AND Entry_Method = 'I'
IF ##ROWCOUNT > 0 GOTO delete_more
SET ROWCOUNT 0
Now the problem is How do i run this thing as i was running it previously through ctx.Database.ExecuteSqlCommand?
What is the way i can run this chunk query code in Linq?
I would create a SQL Server stored procedure that get the employee ids as a parameter. Let's call it 'sp_deleteEmployees' with the param #ids
Then in C# you create a string on the ids
string idsList = "3, 4, 6, 7, 14, 17, 20, 21, 22"
context.Database.ExecuteSqlCommand("usp_CreateAuthor #ids={0} ", idsList);
EDIT
Sorry, I guess I didn't understand the problem. If you need to delete the employees in chunk you can split the list of employee with this
public static List<IEnumerable<T>> Partition<T>(this IEnumerable<T> source, int length)
{
var count = source.Count();
var numberOfPartitions = count / length + ( count % length > 0 ? 1 : 0);
List<IEnumerable<T>> result= new List<IEnumerable<T>>();
for (int i = 0; i < numberOfPartitions; i++)
{
result.Add(source.Skip(length*i).Take(length));
}
return result;
}
You can use this method to split the list to small chunks and delete them one chunk at a time