Error executing MySQL query from an Arduino - mysql

I'm using the following code:
void setup() {
mySerial = new Serial( this, "COM8", 115200 );
output = createWriter( "data.txt" );
msql = new MySQL( this, "localhost", "arduino", "root","" );
if ( msql.connect() )
{output.println("connected");}
else{output.println("not connected");}
// output = open( "data.txt" );
}
void draw() {
if (mySerial.available() > 0 ) {
int d = day();
int m = month();
int y = year();
int s = second(); // Values from 0 - 59
int min = minute(); // Values from 0 - 59
int h = hour();
String a = String.valueOf(d);
String b = String.valueOf(m);
String c = String.valueOf(y);
String value = mySerial.readString();
if ( value != null ) {
output.print( value );
String state=value;
String x=a+"/"+b+"/"+c;
String z=h+":"+min+":"+s;
output.println(x);
output.println(z);
msql.execute( "INSERT INTO info(status,date,time) VALUES ("+state+","+x+","+z+");" );
}
}
But receive this error:
Error: Using driver com.mysql.jdbc.Driver 3.1 SQL.query():
java.sql.SQLException.
INSERT INTO info(status,date,time) VALUES (No detect
,20/3/2015,20:7:23); java.sql.SQLException: You have an error in your
SQL syntax; check the manual that corresponds to your MySQL server
version for the right syntax to use near 'detect ,20/3/2015,20:7:23)'
at line 1
How can this be resolved?

Related

How to update all columns at once in Mysql

There is a database with 200 columns, how to update data from 21 to 200, not in this way -
Set Column21 = NEW.Column21,
Column22 = NEW.Column22,
Column23 = NEW.Column23,
Column24 = NEW.Column24,
Column25 = NEW.Column25...
//You can loop through 22 to 200 and make the string or access property
let sql = "Set",i=22;
[...Array(179)].forEach((_, l) => {
let column = 'Column'+i;
let val = "some val"; //access value
sql += ` ${column} = ${val} `;
i++;
});
console.log(sql);

How to plot CSV values as a Custom Indicator?

I am new to MQL4 and MetaTrader4. I have a CSV file in a following format -
2017.2.1 0:00, 120
2017.2.1 0:05, 123
2017.2.1 0:10, 125
The date format is YYYY.M.D H:MM. I searched other forums, but couldn't get help. I want this to be plotted as an indicator.
about reading data: need to open data, then read its content:
bool ReadFile(const string fileName, string &data){
const int handle=FileOpen(fileName,FILE_READ|FILE_TXT);
if (handle==INVALID_HANDLE) return false;
string collector = "";
int SIZE = (int)FileSize(handle);
int size=StringLen(collector);
while(size < SIZE && !IsStopped()){
collector = StringConcatenate(collector, "\n", FileReadString(handle, SIZE - size));
size = StringLen(collector);
}
FileClose(handle);
if (!FileDelete(fileName))
Print("FileDelete(", fileName, ") FAILED"); // to delete this file after it is read
data = collector;
return true;
}
about parsing each line of the above obtained text:
MqlTime mql;
int st_pos=0,end_pos=0;
int year = 0;
end_pos = StringFind(line, ".", st_pos);
int year = StrToInteger(StringSubStr(line,st_pos+1,end_pos-st_pos-1));
mql.year = year;
// same with month, day, hour and minute
datetime time = StructToTime(mql); - this is your date
after that - find index using iBarShift() that corresponds to your date and Buffer[i] = value that is parsed from the same line

Can't use .Union all with Linq

I have a problem, can you help me.
var query = (from MONHOC in db.tbl_MONHOCs
where
(MONHOC.IS_DELETE != 1 ||
MONHOC.IS_DELETE == null) &&
MONHOC.ISBATBUOC == 1
select new
{
ID = ("MH_CHA_" + Convert.ToString(MONHOC.ID_MONHOC)),
ID_NAME = MONHOC.ID_MONHOC,
MA_MONHOC = MONHOC.MA_MONHOC,
NAME = MONHOC.TEN_MONHOC,
ID_PARENT = 0
}).Concat
(from MONHOC in db.tbl_MONHOCs
where
(MONHOC.IS_DELETE != 1 ||
MONHOC.IS_DELETE == null) &&
MONHOC.ISBATBUOC == 0
select new
{
ID = ("MH_CON_" + Convert.ToString(MONHOC.ID_MONHOC)),
ID_NAME = MONHOC.ID_MONHOC,
MA_MONHOC = MONHOC.MA_MONHOC,
NAME = MONHOC.TEN_MONHOC,
ID_PARENT = (int?) MONHOC.ID_MONHOC_CHA
}
);
Error
Error Compiling Expression: Error Compiling Expression:
'System.Linq.IQueryable' does not contain a
definition for 'Concat' and the best extension method overload
'System.Linq.ParallelEnumerable.Concat(System.Linq.ParallelQuery,
System.Collections.Generic.IEnumerable)' has some invalid
arguments Instance argument: cannot convert from
'System.Linq.IQueryable' to
'System.Linq.ParallelQuery'
The exception message "clearly" :) tells you that the types of the properties in the anonymous types don't match.
In the first part you have:
ID_PARENT = 0
In the second part:
ID_PARENT = (int?) MONHOC.ID_MONHOC_CHA
These properties should both either be int? or int.

C API Support for calling mysql stored procedure

I'm in the phase of developing a C project which interacts with mysql. So i planned to use mysql stored procedure and found a sample program in this link
I just changed the program according to the requirements of my project. Here is the table structure
id | int(10) unsigned | NO | PRI | NULL | auto_increment |
username | varchar(64) | NO | MUL | NULL | |
password | varchar(25) | NO | | NULL | |
And here is my program.
int main()
{
MYSQL_RES *result;
MYSQL *mysql=mysql_init(NULL);
/* connect to server with the CLIENT_MULTI_STATEMENTS option */
if (mysql_real_connect (mysql, "localhost", "root", "root123","DONT_USE", 0, NULL , CLIENT_MULTI_STATEMENTS) == NULL)
{
printf("mysql_real_connect() failed\n");
mysql_close(mysql);
}
MYSQL_STMT *stmt;
MYSQL_BIND ps_params[1]; /* input parameter buffers */
long int int_data[3]; /* input/output values */
my_bool is_null[3]; /* output value nullability */
int status;
char own_buf[25],input_buf[64];
memset(own_buf, 0, 25);
memset(input_buf, 0, 64);
/* set up stored procedure */
status = mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
test_error(mysql, status);
status = mysql_query(mysql,
"CREATE PROCEDURE p1("
" IN p_in VARCHAR(64)) "
"BEGIN "
" SELECT password from data where username=p_in; "
"END");
test_error(mysql, status);
/* initialize and prepare CALL statement with parameter placeholders */
stmt = mysql_stmt_init(mysql);
if (!stmt)
{
printf("Could not initialize statement\n");
}
status = mysql_stmt_prepare(stmt, "CALL p1(?)", 10);
test_stmt_error(stmt, status);
/* initialize parameters: p_in, p_out, p_inout (all INT) */
memset(ps_params, 0, sizeof (ps_params));
ps_params[0].buffer_type = MYSQL_TYPE_STRING;
ps_params[0].buffer = (void *) &input_buf;
ps_params[0].buffer_length = sizeof(input_buf);
ps_params[0].is_null = 0;
/* bind parameters */
status = mysql_stmt_bind_param(stmt, ps_params);
test_stmt_error(stmt, status);
/* assign values to parameters and execute statement */
int_data[0]= 2; /* p_in */
int_data[1]= 20; /* p_out */
strcpy(input_buf,"'6666600222'");
int_data[0] = strlen(input_buf);
input_buf[int_data[0]] = '\0';
ps_params[0].length = &int_data[0];
status = mysql_stmt_execute(stmt);
test_stmt_error(stmt, status);
/* process results until there are no more */
do {
int i;
int num_fields; /* number of columns in result */
MYSQL_FIELD *fields; /* for result set metadata */
MYSQL_BIND *rs_bind; /* for output buffers */
/* the column count is > 0 if there is a result set */
/* 0 if the result is only the final status packet */
num_fields = mysql_stmt_field_count(stmt);
if (num_fields > 0)
{
/* there is a result set to fetch */
printf("Number of columns in result: %d\n", (int) num_fields);
/* what kind of result set is this? */
printf("Data: ");
if(mysql->server_status & SERVER_PS_OUT_PARAMS)
printf("this result set contains OUT/INOUT parameters\n");
else
printf("this result set is produced by the procedure\n");
MYSQL_RES *rs_metadata = mysql_stmt_result_metadata(stmt);
test_stmt_error(stmt, rs_metadata == NULL);
fields = mysql_fetch_fields(rs_metadata);
rs_bind = (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
if (!rs_bind)
{
printf("Cannot allocate output buffers\n");
}
memset(rs_bind, 0, sizeof (MYSQL_BIND) * num_fields);
/* set up and bind result set output buffers */
for (i = 0; i < num_fields; ++i)
{
rs_bind[i].buffer_type = fields[i].type;
rs_bind[i].is_null = &is_null[i];
switch (fields[i].type)
{
case MYSQL_TYPE_LONG:
rs_bind[i].buffer = (char *) &(int_data[i]);
rs_bind[i].buffer_length = sizeof (int_data);
break;
case MYSQL_TYPE_VAR_STRING:
rs_bind[i].buffer = (char *) own_buf;
rs_bind[i].buffer_length = sizeof(own_buf);
rs_bind[i].length = &int_data[1];
break;
default:
fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
}
}
status = mysql_stmt_bind_result(stmt, rs_bind);
test_stmt_error(stmt, status);
/* fetch and display result set rows */
while (1)
{
status = mysql_stmt_fetch(stmt);
if (status == 1 || status == MYSQL_NO_DATA)
break;
for (i = 0; i < num_fields; ++i)
{
switch (rs_bind[i].buffer_type)
{
case MYSQL_TYPE_LONG:
if (*rs_bind[i].is_null)
printf(" val[%d] = NULL;", i);
else
printf(" val[%d] = %ld;",
i, (long) *((int *) rs_bind[i].buffer));
break;
case MYSQL_TYPE_VAR_STRING:
printf(" val[%d] = %s;",i,(char*)rs_bind[i].buffer);
break;
default:
printf(" unexpected type (%d)\n",
rs_bind[i].buffer_type);
}
}
printf("\n");
}
mysql_free_result(rs_metadata); /* free metadata */
free(rs_bind); /* free output buffers */
}
else
{
/* no columns = final status packet */
printf("End of procedure output\n");
}
/* more results? -1 = no, >0 = error, 0 = yes (keep looking) */
status = mysql_stmt_next_result(stmt);
if (status > 0)
test_stmt_error(stmt, status);
} while (status == 0);
mysql_stmt_close(stmt);
}
OUTPUT:
Number of columns in result: 1
Data: this result set is produced by the procedure
End of procedure output
Above code works fine in case of integer argument like CREATE PROCEDURE p1(IN p_in INT) but not for varchar arguments.
link as mentioned in the link for varchar input parameter type is MYSQL_TYPE_STRING and output parameter type is MYSQL_TYPE_VAR_STRING
Problem:
Getting empty result.
As far my analysis, status = mysql_stmt_fetch(stmt); function returns 100(MYSQL_NO_DATA) though the entry present in the table.
NOTE: I tried calling the procedure manually into mysql like call p1('6666600222'); which results
mysql> call p1('6666600222');
+----------+
| password |
+----------+
| 1234 |
+----------+
1 row in set (0.00 sec)
Anyone help me to short out this?
In order to set a varchar param, ps_params should take pointer to char not pointer to pointer to char.
Try change:
ps_params[0].buffer = (void *) &input_buf;
to:
ps_params[0].buffer = (void *)&(input_buf[0]); // or just (void *)input_buf
And after set string value to input_buf set ps_params[0].buffer_length as below:
ps_params[0].buffer_length = strlen(input_buf);
Hope this helps

LinqToSql .Contains and nvarchar vs varchar parameters -> index conversion plan

I have a just one table mapped in a datacontext. Here's the property and attribute on the column of interest:
[Column(Storage="_CustomerNumber", DbType="VarChar(25)")]
public string CustomerNumber
{
This column is, in fact, a varchar(25) and has an index.
I've got some simple code:
DataClasses1DataContext myDC = new DataClasses1DataContext();
myDC.Log = Console.Out;
List<string> myList = new List<string>() { "111", "222", "333" };
myDC.Customers
.Where(c => myList.Contains(c.CustomerNumber))
.ToList();
Which generates this SQL text:
SELECT [t0].[CustomerNumber], [t0].[CustomerName]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[CustomerNumber] IN (#p0, #p1, #p2)
-- #p0: Input NVarChar (Size = 3; Prec = 0; Scale = 0) [111]
-- #p1: Input NVarChar (Size = 3; Prec = 0; Scale = 0) [222]
-- #p2: Input NVarChar (Size = 3; Prec = 0; Scale = 0) [333]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8
Notice that the paramaters are nvarchar!
When this query hits the database, it generates a horrible plan which involves converting the multi-million row index on CustomerNumber to nvarchar before seeking within it.
I'm not allowed to change the table, but I can change the query and the dbml. What can I do to get the data out without getting this index conversion?
Here's the way I solve this problem now-a-days. This converts the parameters to the desired type and then runs the query. It generates the same sql as originally generated, just with different parameter types.
DbCommand myCommand = myDataContext.GetCommand(query);
foreach (DbParameter dbParameter in myCommand.Parameters)
{
if (dbParameter.DbType == System.Data.DbType.String)
{
dbParameter.DbType = System.Data.DbType.AnsiString;
}
}
myDataContext.Connection.Open();
System.Data.Common.DbDataReader reader = myCommand.ExecuteReader();
List<RecordType> result = myDataContext.Translate<RecordType>(reader).ToList();
myDataContext.Connection.Close();
Here's what I've got as a possible work around. I'm interested in seeing other solutions as well:
List<IQueryable<Customer>> myQueries =
myList.Select(s => myDC.Customers.Where(c => c.CustomerNumber == s)).ToList();
IQueryable<Customers> myQuery = myQueries.First();
foreach(IQueryable<Customer> someQuery in myQueries.Skip(1))
{
myQuery = myQuery.Concat(someQuery);
}
myQuery.ToList();
This generates the following SQL:
SELECT [t4].[CustomerNumber], [t4].[CustomerName]
FROM (
SELECT [t2].[CustomerNumber], [t2].[CustomerName]
FROM (
SELECT [t0].[CustomerNumber], [t0].[CustomerName]
FROM [dbo].[Customer] AS [t0]
WHERE [t0].[CustomerNumber] = #p0
UNION ALL
SELECT [t1].[CustomerNumber], [t1].[CustomerName]
FROM [dbo].[Customer] AS [t1]
WHERE [t1].[CustomerNumber] = #p1
) AS [t2]
UNION ALL
SELECT [t3].[CustomerNumber], [t3].[CustomerName]
FROM [dbo].[Customer] AS [t3]
WHERE [t3].[CustomerNumber] = #p2
) AS [t4]
-- #p0: Input VarChar (Size = 3; Prec = 0; Scale = 0) [111]
-- #p1: Input VarChar (Size = 3; Prec = 0; Scale = 0) [222]
-- #p2: Input VarChar (Size = 3; Prec = 0; Scale = 0) [333]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8
For the project I'm working on, we have to use ObjectContext instead of DbContext, so I don't have ready access to GetCommand() or the DbParameters. What I do is convert the query to a string, remove the NVARCHAR indicator in the query, then execute the query against the ObjectContext. Here's a verbose implementation for the example given:
List<string> myList = new List<string>() { "111", "222", "333" };
IQueryable<Customers> badQuery = myDC.Customers
.Where(c => myList.Contains(c.CustomerNumber));
string query = ((System.Data.Objects.ObjectQuery)badQuery).ToTraceString();
query = query.Replace(",N'", ",'").Replace("(N'","('");
List<Customers> customers = myDC.ExecuteStoreQuery<Customers>(query).ToList();