c# System.Data.SQLite.SQLiteException: "SQL logic error unrecognized token: '#' " - c#

I want to Capture network traffic and save the ASCII code in my database and I still got this(is it unsupported character in database?):
Unhandled exception. code = Error (1), message = System.Data.SQLite.SQLiteException (0x800007BF): SQL logic error
unrecognized token: "#"
at System.Data.SQLite.SQLite3.Prepare(SQLiteConnection cnn, String strSql, SQLiteStatement previous, UInt32 timeoutMS, String& strRemain)
at System.Data.SQLite.SQLiteCommand.BuildNextCommand()
at System.Data.SQLite.SQLiteDataReader.NextResult()
at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave)
at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery(CommandBehavior behavior)
at CapturingAndParsingPackets.MainClass.Main(String[] args) in C:\Users\Administrator\CSharp\packetnet-master\packetnet-master\Examples\CapturingAndParsingPackets\Main.cs:line 196
here's my code:
try
{
string sql = $"insert into log (Time, TYPE, DstIP, DstPort, SrcIP, SrcPort, Flag, TotalPacketLength, AsciiCode) values ('{DateTime.Now.ToString("yyyy'-'MM'-'dd HH:mm:ss")}', 'TCP', '{ipPacket.DestinationAddress}', '{tcpPacket.DestinationPort}', '{ipPacket.SourceAddress}', '{tcpPacket.SourcePort}', '{tcpPacket.Flags}', '{tcpPacket.TotalPacketLength}', '{ipPacket.PrintAscii()}')";
SQLiteCommand command = new SQLiteCommand(sql, m_dbconnection);
command.ExecuteNonQuery();
m_dbconnection.Close();
}
catch(Exception) //if Ascii code is too long
{
string sql = $"insert into log (Time, TYPE, DstIP, DstPort, SrcIP, SrcPort, Flag, TotalPacketLength, AsciiCode) values ('{DateTime.Now.ToString("yyyy'-'MM'-'dd HH:mm:ss")}', 'TCP', '{ipPacket.DestinationAddress}', '{tcpPacket.DestinationPort}', '{ipPacket.SourceAddress}', '{tcpPacket.SourcePort}', '{tcpPacket.Flags}', '{tcpPacket.TotalPacketLength}', 'Encrypted Code')";
SQLiteCommand command = new SQLiteCommand(sql, m_dbconnection);
command.ExecuteNonQuery();
m_dbconnection.Close();
}
And this is my database structure:
string sql = "create table log(PacketID INTEGER PRIMARY KEY AUTOINCREMENT, Time DATETIME," +
"TYPE CHAR(6) NULL DEFAULT '', DstIP varchar(15), DstPort INT, SrcIP varchar(15), SrcPort INT, Flag varchar(2), TotalPacketLength INT, AsciiCode BLOB)";
SQLiteCommand command = new SQLiteCommand(sql, m_dbconnection);
command.ExecuteNonQuery();

A Simple Wrapper class I provided on another answer.
You should never build a SQL command like you are. You will be open to SQL-Injection which is bad. By working directly with a class structure object that matches your table, this might offer better control and readability without the exposure to injection and bad formatting of string commands.

Related

C# Exception with MySQL UPDATE query

Recently, I have been working on a C# plugin for a game I play. My problem at the moment is that the query listed below is generating many errors, such as these errors:
MySql.Data.MySqlClient.MySqlException: Data too long for column 'lastServer' at row 1
^^This error shows when my lastServer data type is varchar(10), but when I changed it to varchar(25), it went away. However I would still like to know why this would be, if anyone is able to figure it out.
.
My current error is having #lastServer, #characterName, and #ip showing up as #lastServer, #characterName, and #ip instead of their "AddWithValue" values.
Here's the query used for Table Creation:
command.CommandText = string.Concat("CREATE TABLE `", MDiscipline.Instance.Configuration.Instance.PlayerInfoTableName, "` (`steamId` varchar(32) NOT NULL,`characterName` varchar(40) NOT NULL,`ip` varchar(15) NOT NULL, `lastPunishment` tinyint(2) UNSIGNED NOT NULL,`lastServer` varchar(25) NOT NULL,`lastLogin` TIMESTAMP NOT NULL DEFAULT current_timestamp, PRIMARY KEY (`steamId`)) ");
And Here is the Code I'm having problems with:
public void UpdatePlayerInfo(string steamid, string characterName, string ip)
{
try
{
MySqlConnection connection = createConnection();
MySqlCommand command = connection.CreateCommand();
command.Parameters.AddWithValue("#steamId", steamid);
command.Parameters.AddWithValue("#characterName", characterName);
command.Parameters.AddWithValue("#ip", ip);
command.Parameters.AddWithValue("#lastServer", MDiscipline.Instance.Configuration.Instance.Instance);
command.CommandText = "UPDATE `" + MDiscipline.Instance.Configuration.Instance.PlayerInfoTableName + "` SET `characterName` = '#characterName', `ip` = '#ip', `lastServer` = '#lastServer', `lastLogin` = NOW() WHERE `steamId` = '" + steamid.ToString() + "';";
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
catch (Exception ex)
{
Logger.LogException(ex);
}
}
Helpful info to understand variables:
MDiscipline.Instance.Configuration.Instance.PlayerInfoTableName can be translated to "player_info".
steamid or (#steamId) can be translated to a 32 char number.
characterName or (#characterName) can be translated to any value between 1 and 30 characters.
ip or (#ip) can be translated to an ip address in a string, such as "255.255.255.255".
MDiscipline.Instance.Configuration.Instance.Instance or (#lastServer) can be translated to Server01.

Syntax error in INSERT INTO statement ASP.Net C#

First of all, yes I know there are several other questions about this. I have reviewed and tried different solutions proposed in them; however I'm still getting a "Syntax error INSERT INTO statement" message when I click on the submit button to run the function.
I'm running VS 2015 and an Access 2010 db. The full error message is as follows:
Data.OleDb.OleDbException (0x80040E14): Syntax error in INSERT INTO
statement. at
System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult
hr) at
System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS
dbParams, Object& executeResult) at
System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object&
executeResult) at
System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior
behavior, String method) at
System.Data.OleDb.OleDbCommand.ExecuteNonQuery() at
createAcc.btnCreateAccount_Click(Object sender, EventArgs e) in
e:\Documents\Visual Studio
2015\WebSites\OneStopFurniture\createAcc.aspx.cs:line 43
My code for the button handler is as follows:
protected void btnCreateAccount_Click(object sender, EventArgs e)
{
connection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=E:\\Documents\\Visual Studio 2015\\WebSites\\OneStopFurniture\\App_Data\\OneStopFur.accdb";
string InsertQuery;
try
{
connection.Open();
OleDbCommand cmdInsert = new OleDbCommand();
cmdInsert.Connection = connection;
InsertQuery= "INSERT INTO [userInfo] (
userName, password, firstName, lastName, userAddress, userCity, userZip, userPhone, userEmail
) VALUES (
#userName, #password, #firstName, #lastName, #userAddress, #userCity, #userState, #userZip, #userPhone, #userEmail
)";
cmdInsert.Parameters.AddWithValue("#userName", txtUserName.Text);
cmdInsert.Parameters.AddWithValue("#password", txtPassword.Text);
cmdInsert.Parameters.AddWithValue("#firstName", txtFirstName.Text);
cmdInsert.Parameters.AddWithValue("#lastName", txtLastName.Text);
cmdInsert.Parameters.AddWithValue("#userAddress", txtAddress.Text);
cmdInsert.Parameters.AddWithValue("#userCity", txtCity.Text);
cmdInsert.Parameters.AddWithValue("#userState", txtState.Text);
cmdInsert.Parameters.AddWithValue("#userZip", txtZip.Text);
cmdInsert.Parameters.AddWithValue("#userPhone", txtPhone.Text);
cmdInsert.Parameters.AddWithValue("#userEmail", txtEmail.Text);
cmdInsert.CommandText = InsertQuery;
cmdInsert.ExecuteNonQuery();
lblConfirm.Visible = true;
lblConfirm.Text = "Account creation successful.";
}
catch (Exception ex)
{
lblConfirm.Visible = true;
lblConfirm.Text = "Unable to create" + ex;
}
}
Can someone please tell me what I am overlooking here? At this point, I'm at a complete lose.
Thanks.
Missing UserState in column list.
InsertQuery= "INSERT INTO [userInfo]
([userName], [password], [firstName], [lastName], [userAddress], [userCity], [userState], [userZip], [userPhone], [userEmail])
VALUES(#userName, #password, #firstName, #lastName, #userAddress, #userCity, #userState, #userZip, #userPhone, #userEmail)";
The good practise is to qoute everything to avoid collision with keywords.
The immediate error is caused by the word Password. This is a reserved keyword in MS-Access. Use square brackets around it.
InsertQuery= #"INSERT INTO [userInfo](userName, [password], firstName,
lastName, userAddress, userCity, userState, userZip,
userPhone, userEmail)
VALUES(#userName, #password, #firstName,
#lastName, #userAddress, #userCity, #userState, #userZip,
#userPhone, #userEmail)";
After fixing this error you need also to add the column UserState (or whatever is called) because you have added a parameter for it.
Keep in mind that in OleDb the parameters are positional. This means the the first field receives the value from the first parameter, whatever name you have used, so missing a field or inverting the position of a parameter in the collection could cause bugs very difficult to spot. Double your checks here.

Can't import foreign key in MySQL DB using C#, Visual Studio and MySQL.Data

I am getting data from MSSQL DB with Entity Framework using C# and Visual Studio and importing it in MySQL DB using MySQL.Data nuget package and C# and Visual Studio again. If I have data without foreing keys everything is OK and the import is done. Here is the code:
var context = new SupermarketsChainEntities();
var measures = context.Measures;
var supermarkets = context.Supermarkets;
var vendors = context.Vendors;
var expenses = context.Expenses;
var products = context.Products;
String myConn = "server=localhost;Database=supermarkets_chain;uid=root;pwd=;";
MySqlConnection conn = new MySqlConnection(myConn);
conn.Open();
//Insert measures
foreach (var measure in measures)
{
String insertQuery = "insert into measures (id, name) values (null, #name)";
MySqlCommand cmd = new MySqlCommand(insertQuery, conn);
cmd.Parameters.AddWithValue("#name", measure.Name);
cmd.ExecuteNonQuery();
}
But when I try to import data in table with one-to-many relationships and foreign keys:
foreach (var product in products)
{
String insertQuery = "insert into products (id, name, price, measure_id, vendor_id) values (null, #name, #price, #measure_id, #vendor_id)";
MySqlCommand cmd = new MySqlCommand(insertQuery, conn);
cmd.Parameters.AddWithValue("#name", product.Name);
cmd.Parameters.AddWithValue("#price", product.Price);
cmd.Parameters.AddWithValue("#measure_id", product.Measure);
cmd.Parameters.AddWithValue("#vendor_id", product.Vendor);
cmd.ExecuteNonQuery();
}
something goes wrong and I get the following exception:
Unhandled Exception: MySql.Data.MySqlClient.MySqlException: Cannot add or update
a child row: a foreign key constraint fails (`supermarkets_chain`.`products`, C
ONSTRAINT `fk_products_measures` FOREIGN KEY (`measure_id`) REFERENCES `measures
` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& i
nsertedId)
at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affected
Rows, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior
)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
at SqlToMysql.Program.Main(String[] args) in d:\SoftUni\DatabaseApps\Teamwork
\SqlToMysql\SqlToMysql\Program.cs:line 67
Can someone help me handle the problem and import the data properly. I am attaching the DB schema here.

mysql query truncated after increasing 'max_allowed_packet'

I have a stored procedure in c# that I add values to and then execute:
string query = "INSERT INTO equipment_parameter (parameter_group_name, version, operation_name, parameter_name, parameter_value, default, owner, date_created) VALUES(#parameter_group_name, #version, #operation_name, #parameter_name, #parameter_value, #default, #owner, #date_created)"; //stored procedure
//open connection
if (mySQLA.OpenConnection() == true)
{
//create command
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = mySQLA.getConnection();
cmd.CommandText = query;
cmd.Prepare();
//string
cmd.Parameters.AddWithValue("#parameter_group_name", eParam.ParameterGroupName);
//int
cmd.Parameters.AddWithValue("#version", eParam.Version);
//string
cmd.Parameters.AddWithValue("#operation_name", eParam.OperationName);
//string
cmd.Parameters.AddWithValue("#parameter_name", eParam.ParameterName);
//double
cmd.Parameters.AddWithValue("#parameter_value", eParam.ParameterValue);
//bool
cmd.Parameters.AddWithValue("#default", eParam.Default);
//string
cmd.Parameters.AddWithValue("#owner", eParam.Owner);
//DateTime
cmd.Parameters.AddWithValue("#date_created", eParam.DateCreated);
//Execute command
try
{
rowsCreated = cmd.ExecuteNonQuery(); //returns number of rows affected
}
catch (MySqlException es)
{
MessageBox.Show(es.Message, "Equipment Parameter Query Error: ");
}
When I run this program it attempts the insertion and then I catch the exception which states:
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 'default, owner, date_created) VALUES('object1', 1, 'Op1', 'object1', 10.01, 1, '' at line 1
The query I'm trying to execute would read something like:
INSERT INTO equipment_parameter (parameter_group_name, version, operation_name, parameter_name, parameter_value, default, owner, date_created) VALUES('object', 1, 'Op1', 'object1', 10.01, false, 'James', '2013-10-30 09:00:54')
I have already increased 'max_allowed_packet' to 500M and restarted the server though this had no effect. Are there other buffer-size options I can increase or what may be my problem?
After boiling my head with this I've just realised that default is a reserved word. As such, it has to be backticked:
[...] parameter_value, `default`, owner, date_created) [...]

Conversion failed when converting datetime from character string

I am developing a C# VS 2008 / SQL Server 2005 Express website application. I have tried some of the fixes for this problem but my call stack differs from others. And these fixes did not fix my problem. What steps can I take to troubleshoot this?
Here is my error:
System.Data.SqlClient.SqlException was caught
Message="Conversion failed when converting datetime from character string."
Source=".Net SqlClient Data Provider"
ErrorCode=-2146232060
LineNumber=10
Number=241
Procedure="AppendDataCT"
Server="\\\\.\\pipe\\772EF469-84F1-43\\tsql\\query"
State=1
StackTrace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at ADONET_namespace.ADONET_methods.AppendDataCT(DataTable dt, Dictionary`2 dic) in c:\Documents and Settings\Admin\My Documents\Visual Studio 2008\WebSites\Jerry\App_Code\ADONET methods.cs:line 102
And here is the related code. When I debugged this code, "dic" only looped through the 3 column names, but did not look into row values which are stored in "dt", the Data Table.
public static string AppendDataCT(DataTable dt, Dictionary<string, string> dic)
{
if (dic.Count != 3)
throw new ArgumentOutOfRangeException("dic can only have 3 parameters");
string connString = ConfigurationManager.ConnectionStrings["AW3_string"].ConnectionString;
string errorMsg;
try
{
using (SqlConnection conn2 = new SqlConnection(connString))
{
using (SqlCommand cmd = conn2.CreateCommand())
{
cmd.CommandText = "dbo.AppendDataCT";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn2;
foreach (string s in dic.Keys)
{
SqlParameter p = cmd.Parameters.AddWithValue(s, dic[s]);
p.SqlDbType = SqlDbType.VarChar;
}
conn2.Open();
cmd.ExecuteNonQuery();
conn2.Close();
errorMsg = "The Person.ContactType table was successfully updated!";
}
}
}
Here is my SQL stored proc:
ALTER PROCEDURE [dbo].[AppendDataCT]
#col1 VARCHAR(50),
#col2 VARCHAR(50),
#col3 VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #TEMP DATETIME
SET #TEMP = (SELECT CONVERT (DATETIME, #col3))
INSERT INTO Person.ContactType (Name, ModifiedDate)
VALUES( #col2, #TEMP)
END
The input file has 3 columns. The first two are varchars, but the 3rd one is also varchar I think, but it's represented as "3/11/2010". In this input file, a sample row looks like:
"Benjamin|breakfast|3/11/2010".
And I am trying to convert this date field from a string to a datetime here in my SP. Am I going about it the wrong way?
DataRow:
col1|col2|col3
11|A2|1/10/1978
12|b2|2/10/1978
13|c2|3/10/1978
14|d2|4/10/1978
I think Belousov Pavel is correct. Inside your foreach you assign each dictionary item as a parameter. Each of those parameters are defined as being VarChar. With the information provided it is logical to assume the problem is in the stored procedure.
Can you either post the code of the stored procedure or try and recreate the error inside SQL Management Studio by executing the stored procedure there.
UPDATE...
After looking at your stored procedure the code looks correct. I was able to generate the error message you are getting using the following sql code.
declare #col3 varchar(50)
set #col3 = '|3/11/2010'
declare #temp datetime
set #temp = (select convert(datetime,#col3))
Note that the value of #col3 starts with a pipe character. If you remove the pipe character it works correctly.
I would look closer at the values in the dictionary you are getting you parameter values from. There may be an issue with the way you parsed the data.
UPDATE 2
The code below is not confirmed to work but I think I see what you are trying to do. I assume the DataTable you are passing in has data like this:
col1|col2|col3
11|A2|1/10/1978
12|b2|2/10/1978
13|c2|3/10/1978
14|d2|4/10/1978
If this is the case we don't need the dictionary that was passed in originally. I can also assume that you want the stored procedure to be executed once for each row in the DataTable. The below method is similar to what you where doing although it runs the stored procedure for each row.
What I am not sure from you explanation is if the first row of the DataTable contains the names of the columns, if not no worries then. Hope this makes sense, leave more comments if you have questions.
public static string TestMethod(DataTable dt)
{
string connString = "";
string errorMsg = string.Empty;
try
{
//loop through each row of the datatable. Not sure if the column names is a row.
foreach (DataRow row in dt.Rows)
{
using (SqlConnection conn2 = new SqlConnection(connString))
{
using (SqlCommand cmd = conn2.CreateCommand())
{
cmd.CommandText = "dbo.AppendDataCT";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn2;
cmd.Parameters.Add(new SqlParameter() { ParameterName = "#col1", SqlDbType = SqlDbType.VarChar, Value = row[0] });
cmd.Parameters.Add(new SqlParameter() { ParameterName = "#col2", SqlDbType = SqlDbType.VarChar, Value = row[1] });
cmd.Parameters.Add(new SqlParameter() { ParameterName = "#col3", SqlDbType = SqlDbType.VarChar, Value = row[2] });
conn2.Open();
cmd.ExecuteNonQuery();
conn2.Close();
}
}
}
errorMsg = "The Person.ContactType table was successfully updated!";
}
catch
{
}
return errorMsg;
}
Well, if you do this:
SqlParameter p = cmd.Parameters.AddWithValue(s, dic[s]);
p.SqlDbType = SqlDbType.VarChar;
all your parameters will be of type VARCHAR. This might sound smart at first - it's not.
If you pass dates as varchar, you start getting into the messy business of date/time string formats - unless you always use the ISO-8601 format YYYYMMDD which works on any SQL Server installation, and with any locale / language / date setting. Anything else becomes a gamble. Not the whole world uses the MM/DD/YYYY format as in the US, and depending on your SQL Server's language or date format settings, your date might not be recognized, or even misinterpreted. Just don't do it - it's a mess.
Plus, really - if you have a date/time in your C# code - I would strongly recommend you pass that as a SqlDbType.DateTime to your SQL Server stored proc. You're just gonna save yourself endless hours of debugging and messy conversions and stuf.......
Problem is in stored procedure, I think. May be one of input parameters is DateTime, but you wrote VarChar to this parameter.
UPDATE:
As I can see you don't use DataTable dt in your method AppendDataCT.
You wrote that dic contains values [0]:[col1, col1] [1]:[col2, col2] [2]:[col3, col3]. But it's wrong values... your code is
SqlParameter p = cmd.Parameters.AddWithValue(s, dic[s]);
Then you send to col3 value = col3, as I understand.
May be you wanted to write
SqlParameter p = cmd.Parameters.AddWithValue(s, dt[s]);
or something like this...
You need to loop through the rows of the DataTable to get the data - you're adding the values of dic (your column names for month, day, year??) as SqlParameters..... This is what I'm assuming because the question is pretty scattered....
Note: Not completely functioning code -
foreach(DataRow dr in dt.Rows)
{
DateTime date = new DateTime();
foreach(string s in dic.Keys)
{
switch(dic[s])
{
case "Month":
date.Month = dr[dic[s]];
break;
case "Day":
date.Day = dr[dic[s]];
break;
case "Year":
date.Year = dr[dic[s]];
break;
}
}
// If valid date
SqlParameter p = cmd.Parameters.AddWithValue("Date", date);
p.SqlDbType = SqlDbType.DateTime;
}
UPDATE: You will need to handle your own data validation - otherwise, here you go
using (SqlConnection conn2 = new SqlConnection(connString))
{
using (SqlCommand cmd = conn2.CreateCommand())
{
conn2.Open();
foreach(DataRow dr in dt.Rows)
{
SqlParameter col1 = cmd.Parameters.AddWithValue(dic[0], dr[0].ToString());
SqlParameter col2 = cmd.Parameters.AddWithValue(dic[1], dr[1].ToString());
SqlParameter col3 = cmd.Parameters.AddWithValue(dic[2], Convert.ToDateTime(dr[2]));
cmd.ExecuteNonQuery();
}
conn2.Close();
}
}
In my case I had my INSERT query's values in the wrong order:
INSERT INTO my_table(
status --varchar
, created_on --datetime2
) VALUES (
#created_on --datetime2
, #status --varchar
)

Categories

Resources