Sql insert command in C# - c#

I'm currently creating a small C# program that inserts data from files into a postgres table.
The code that does the insertion looks like this:
NpgsqlCommand cmd = new NpgsqlCommand(#"INSERT INTO :table(text) VALUES (:word);", con);
cmd.Parameters.AddWithValue("table", table);
cmd.Parameters.AddWithValue("word", line);
cmd.ExecuteNonQuery();
But every time it tries to execute the "ExecuteNonquery" line I get the following error:
An unhandled exception of type 'Npgsql.NpgsqlException' occurred in Npgsql.dll
Additional information: ERROR: 42601: syntax error at or near "("
I can connect to the database I have checked. The variables table and line also have the correct values at runtime. I just can't figure out what the problem is..
Any suggestions ?

As far as I know the table can't be a parameter.
What you can do however is use string concatting/formatting for that:
string table = "table";
NpgsqlCommand cmd = new NpgsqlCommand(string.Format(#"INSERT INTO {0}(text) VALUES (:word);", table), con);
Guess that would work (didn't test it).

Related

Sending time to SQL Server Management Studio table but it does not display?

I am currently writing an application which involves a user being able to write the time to a database by clicking a button. The problem is that the data will be send to the database table, but it does not show the time in SQL Server Management Studio.
This is my query:
{
string query = "insert into Sign_In_Out_Table(Sign_In)Values('"+ timetickerlbl.ToString()+ "')";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#SignIn", DateTime.Parse (timetickerlbl.Text));
//cmd.ExecuteNonQuery();
MessageBox.Show("Signed in sucessfully" +timetickerlbl);
con.Close();
}
The datatype in SQL Server is set to datetime.
I'm open for suggestions to find a better way to capture the PC's time and logging it in a database.
Don't wrap the variable in ' when you are setting value with Parameters.Add(), or Parameters.AddWithValue() as they would wrap if needed.
The variable in here would be the value of Sign_In and not the Sign_In itself.
Always use Parameters.Add() instead of Parameters.AddWithValue():
string query = "insert into Sign_In_Out_Table(Sign_In) Values(#value)";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add("#value", SqlDbType.DateTime).Value = DateTime.Parse(timetickerlbl.Text);
Edit (Considering your comment):
If still it does not insert it, of course there is an error in your code, it could be a syntax error, invalid table or column name, connection problem ,... so put your code in a try-catch block (if it isn't already) and see what error you you get, it should give you a hint:
try
{
//the lines of code for insert
}
catch(Exception ex)
{
string msg = ex.Message;
// the above line you put a break point and see if it reaches to the break point, and what the error message is.
}
Your table does not contain your timestamp because you have commented the execution of your query. Presumably you added the comment because this line was throwing an error, remove the comment and share the error with us.
cmd.ExecuteNonQuery();

Conversion failed in SQL procedure while executing from C#

I have a SQL stored procedure which uses openrowset command and fetches values from an excel sheet and inserts it into the database.
I have created a C# application which will call the procedure and execute it.
PROBLEM!
When I execute the procedure from SQL management studio, there are no errors. It happens perfectly. But when I execute it through the C# application I get an error: "Conversion failed when converting date and/or time from character string."
Code
SQL Query (only the insert part)
insert into tbl_item ([Item code],[Dt Created])
select[Item code] ,
case when [Dt Created] is null or [Dt Created]='' then null when ISDATE(CONVERT(nvarchar,CONVERT(datetime, [Dt Created],103))) =1 then CONVERT(datetime, [Dt Created],103) else null end as [Dt Created]
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0','Excel 12.0; Database=C:\Upload\Report.xlsx;HDR=YES;IMEX=1;',
'select * from [Sheet1$]')
C# Code
public int updateItem()
{
SqlCommand cmd; cmd = new SqlCommand("usp_updateItem", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter returnParameter = cmd.Parameters.Add("RetVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
try
{
if (conn.State.Equals(ConnectionState.Closed))
conn.Open();
cmd.ExecuteNonQuery();
ret = Convert.ToInt32(returnParameter.Value);
}
catch (Exception e)
{
err = "Error: " + e.Message;
return -1;
}
finally
{
conn.Close();
}
return ret;
}
What is the format you are having in the [Dt Created] variable.
the convert statement you have in the case will convert only the following types below
YYYY-MM-DD
YYYY-DD-MM
DD-MM-YYYY
The error you are getting is since you have a date in the format of "MM-DD-YYYY" something like '12-24-2015'. Due to this you are getting the conversion error.
Excuse me I want to stop you here. Your problem has resolved now but whatever
Karthik Venkatraman had said is correct. Somehow you got solution but for learning purpose i recommended to investigate little bit more. This is not belongs to the whatever you have said but damm sure this belongs to date-format.
**
One trick
Create one DateTimeVariable and once its initialized then just parse it using DateTimeParse class according to the records exist in database.
I am sure you will get solution.. Thanks :)
This is how I finally solved it...
The SQL error message 'Failed Conversion' was absolutely a wrong pointer. It had no connection to the issue at hand. [If only I knew this before :( ]
The actual problem was that I had called another procedure within the main procedure I had posted above. This setup ran perfectly in SQL management studio which was running under my credentials. Now in the C# application, I had created another SQL login user ID to run it. And this user ID did not have execute permission to run the sub procedure. And ironically, SQL gave me a misleading conversion error. Once I gave the right permission it worked perfectly.

How can I display a message if a value already exists in database?

I am currently writing my first .Net & C# application with Visual Studio, and have a need to write generated values to MySQL from the application.
At present, I can write values fine - but I need to be able to check to see if a value exists and display that line if it does exist, otherwise insert new line to table. My connection string is defined at the top of the form.
I have the following defined already, and it writes to the database successfully if no duplicate values exist in the LicenseKey column. If a duplicate exists, it throws an unhandled exception.
private void SaveDetails()
{
// MySQL 'insert' command
string InsertNewLicense = "insert into BCOM.LicenseDetails(LicenseeName,ComputerName,ContactName,ContactEmail,LicenseKey,CreationDate) values('" +this.textBoxLicenseeName.Text+ "','" +this.textBoxComputerName.Text+ "','" +this.textBoxContactName.Text+ "','" +this.textBoxContactEmail.Text+ "','" +this.textBoxLicenseKey.Text+ "','" +this.textBoxCreationDate.Text+ "');";
//MySQL instance details
MySqlConnection InsertLicenseDetails = new MySqlConnection(LicenseDatabaseConnection);
//MySQL command execution
MySqlCommand InsertCommand = new MySqlCommand(InsertNewLicense, InsertLicenseDetails);
// Handles command outputs.
MySqlDataReader InsertReader;
//Opens connection to run query on database
InsertLicenseDetails.Open();
// Here our query will be executed and data saved into the database.
MessageBox.Show("License Details Saved. Please ensure you have emailed the license to the customer.");
while (InsertReader.Read())
{
}
InsertLicenseDetails.Close();
}
What I want to happen is for a check to be run on the LicenseKey column to see if the value exists, before different actions are taken.
If the value does not exist, I would like to insert the new line to the table (like my existing command does).
If, however, the value does exist, I would like to pop up a form showing the values from the line that the duplicate appears in as a form.
Where would I put in an event handler to read MySQLException values? What exception would I have to respond to for a duplicate value or no database response?
I agree with what the others have said in their comments, you could change the SQL Query to do the check instead of having 2.
IF(SELECT ... WHERE A = B)
RETURN THAT THE VALUE ALREADY EXISTS
ELSE
INSERT NEW VALUE
Also there was a good comment about SQL Injection and parameterized queries. The query string should look a bit more like
INSERT into BCOM.LicenseDetails(LicenseeName,ComputerName,ContactName,ContactEmail,LicenseKey,CreationDate) values(#LicenseeName, #ComputerName, #ContactName ...);
and your SqlCommand be parameterized
InsertCommand.Paramaters.AddWithValue("#LicenseeName", this.textBoxLicenseeName.Text);
InsertCommand.Paramaters.AddWithValue("#ComputerName", this.textBoxComputerName.Text);
...
That should be a good start to get you going.
After looking at the queries for a while I decided to try a different tack - instead of using a direct check if it's there, I opted to use a count(*) query. When I click the save button on the form, the buttonClick_event calls SaveDetails(), which runs the following:
private void SaveDetails()
{
string InsertNewLicense = "INSERT into BCOM.LicenseDetails(LicenseeName,ComputerName,ContactName,ContactEmail,LicenseKey,CreationDate) values(#LicenseeName, #ComputerName, #ContactName, #ContactEmail, #LicenseKey, #CreationDate)";
string LicenseExistence = "SELECT COUNT(*) FROM BCOM.LicenseDetails WHERE LicenseKey LIKE #LicenseKey";
MySqlConnection LicenseDetails = new MySqlConnection(LicenseDatabaseConnection);
MySqlCommand InsertCommand = new MySqlCommand(InsertNewLicense, LicenseDetails);
InsertCommand.Parameters.AddWithValue("#LicenseeName", this.textBoxLicenseeName.Text);
InsertCommand.Parameters.AddWithValue("#ComputerName", this.textBoxComputerName.Text);
InsertCommand.Parameters.AddWithValue("#ContactName", this.textBoxContactName.Text);
InsertCommand.Parameters.AddWithValue("#ContactEmail", this.textBoxContactEmail.Text);
InsertCommand.Parameters.AddWithValue("#LicenseKey", this.textBoxLicenseKey.Text);
InsertCommand.Parameters.AddWithValue("#CreationDate", this.textBoxCreationDate.Text);
MySqlCommand QueryCommand = new MySqlCommand(LicenseExistence, LicenseDetails);
QueryCommand.Parameters.AddWithValue("#LicenseKey", this.textBoxLicenseKey.Text);
MySqlDataReader InsertReader;
LicenseDetails.Open();
if ((int)(long)QueryCommand.ExecuteScalar() >0)
{
MessageBox.Show("This license already exists in the database.");
}
else
{
InsertReader = InsertCommand.ExecuteReader();
MessageBox.Show("License Details Saved. Please ensure you have emailed the license to the customer.");
while (InsertReader.Read())
{
}
}
LicenseDetails.Close();
So, if the query against the license keys returns with any results at all (more than 0 rows returned), a messagebox pops up showing that the key already exists. If the resultant number of rows is 0, the insert command gets run.
This was figured out with a look through MySQL command notes, testing with phpMyAdmin, matching against existing projects online, and support from the following:
The SELECT query was figured out with great support from #Seige.
The query was parameterized with help from Seige, following on from the advice of Sani Huttunen. Many thanks to them both.
Changing to the count method was done on the advice of a fellow coder in another community online - a good friend and brilliant coder.

MySql command "load data infile" execution error in C#

I am trying to import a text file into MySql database using C# code but getting errors.
My table structure is:
and the C# code that I'm executing is:
fileQuery =
"load data infile '{0}' into table dgl.deliveries fields terminated by '\t' lines terminated by \r\n' (#ImagePath, Delivery_Note, Shipment_Number, #Delivery_Date, Deliver_To_Code, Deliver_To_Name, Sold_To_Code, Sold_To_Name, Material_Number, Doctype) set Delivery_Date = tr_to_date(#Delivery_Date, '%d/%m/%Y'), ImagePath = Concat('USERFILES/', #ImagePath)";
string q = string.Format(fileQuery,fileName);
MySqlConnection conn = new MySqlConnection(dglConnection.ConnectionString);
MySqlCommand command = conn.CreateCommand();
command.CommandText = q;
conn.Open();
command.ExecuteNonQuery();
and the error is:
An exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.DLL but was not handled in user code
Additional information: 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 '%d/%m/%Y'), ImagePath = Concat('USERFILES/', #ImagePath)' at line 2
The following is a line from source input file:
123.pdf 802661341 1061611 18/02/2015 00:00:00 22280 ABC LIMITED 22280 XYZ LIMITED 30679795 30744488 DELIVERY NOTE 1
Your problem is that Your Date that you are passing from your C# code is 18/02/2015. Mysql only excepts a date in the format YYYY-MM-DD. You need to adjust that data so that it formats to the way Mysql will except a date if you want to store it as a date.
I actually wrote a stored procedure that you maybe able to use (or at least get an idea of what needs to be done): Here is the link.
Also when in doubt just refer to dev.mysql its a great resource also.

SQL anywhere query error: Not enough values for host variables

I am building a query using ODBC command object in .Net with multiple parameters being passed in. When executing the query against SQL Anywhere, I get the following error. (The same code works against SQL Server).
[System.Data.Odbc.OdbcException] = {"ERROR [07002] [Sybase][ODBC Driver][SQL Anywhere]Not enough values for host variables"}
The command object has the same number of parameters added as the place holders ('?') in the query. Following is a simple query and C# code that fails the test.
C# code to populate the host variables
String queryText= #"DECLARE #loanuseraddress varchar(40), #loanid decimal
Set #loanid = ?
Set #loanuseraddress = ?
select * from loan_assignments where loan_id = #loanid"
OdbcConnection connection = new OdbcConnection(request.ConnectionString);
OdbcCommand command;
command = new OdbcCommand(queryText, connection);
OdbcParameter param1 = new OdbcParameter("#loanid", OdbcType.Decimal);
param1.Value = request.Loan.LoanNumber;
command.Parameters.Add(param1);
OdbcParameter param2 = new OdbcParameter("#loanuseremployer", dbcType.VarChar);
param2.Value = appraisalCompanyUpdate.LoanUserEmployer;
if (param2.Value == null)
param2.Value = DBNull.Value;
command.Parameters.Add(param2);
connection.Open();
OdbcDataReader rows = command.ExecuteReader();
I fixed this by checking for nulls. When you try to pass a null parameter to Sybase, that's the error you get (at least for me). Have a feeling LoanId is null at some point.
Edit After doing a little more research, I think you can also get this error when you try multiple insert / deletes / updates through the Sybase ODBC Connection in .Net. I don't think this is supported and MSDN seems to say it's vendor specific.
"Insufficient host variables" can also mean something else but it's applicable to the OP:
one of the other causes could be that you have a set of declared variables different from the set your SQL statement is using.
E.g. this could be a typo, or you could have copied in SQL from Visual Studio that was used to fill a dataset table using parameters (like :parm) but in doing so you forgot to declare it (as #parm) in your stored proc or begin/end block.

Categories