My application with C#2010 and database in Access2003, I want to insert new recrord into my table by the it has an error:
"syntax error in insert into statement"
private void button3_Click(object sender, EventArgs e)
{
String ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + "\\New.mdb";
OleDbConnection myconection = new OleDbConnection(ConnectionString);
try
{
OleDbCommand mycomand = new OleDbCommand();
mycomand.CommandText = "INSERT INTO Refugees Characteristic(Nr,First Name,Last Name,Birthday,Country,City,Insurance Nr,Gander,Marital status,Nr of Children,Address,Mother Tongue,Other Languages,Phone Nr,Enter to Austria,Education,Skills,Picture) VALUES (#p1,#p2,#p3,#p4,#p5,#p6,#p7,#p8,#p9,#p10,#p11,#p12,#p13,#p14,#p15,#p16,#p17,#p18)";
mycomand.Parameters.Clear();
mycomand.Parameters.AddWithValue("#p1", IdTxt.Text);
mycomand.Parameters.AddWithValue("#p2", FirstTxt.Text);
mycomand.Parameters.AddWithValue("#p3", LasttextBox.Text);
mycomand.Parameters.AddWithValue("#p4", BirthdayTxt.Text);
mycomand.Parameters.AddWithValue("#p5", CountryTxt.Text);
mycomand.Parameters.AddWithValue("#p6", CityTxt.Text);
mycomand.Parameters.AddWithValue("#p7", InsuranceTxt.Text);
mycomand.Parameters.AddWithValue("#p8", GanderBox.Text);
mycomand.Parameters.AddWithValue("#p9", marriedTxt.Text);
mycomand.Parameters.AddWithValue("#p10", ChildnumTxt.Text);
mycomand.Parameters.AddWithValue("#p11", AddressTxt.Text);
mycomand.Parameters.AddWithValue("#p12", MotherTongTxt.Text);
mycomand.Parameters.AddWithValue("#p13", OtherlanTxt.Text);
mycomand.Parameters.AddWithValue("#p14", phonNumberTxt.Text);
mycomand.Parameters.AddWithValue("#p15", EnterTxt.Text);
mycomand.Parameters.AddWithValue("#p16", EducationTxt.Text);
mycomand.Parameters.AddWithValue("#p17", SkillsTxt.Text);
mycomand.Parameters.AddWithValue("#p18", PicLocationtxt.Text);
// mycomand.Connection = null;
mycomand.Connection = myconection;
myconection.Open();
mycomand.ExecuteNonQuery();
MessageBox.Show("New Record is Added");
myconection.Close();
myconection.Dispose();
mycomand.Dispose();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
If your table names and column names are two words, you need to use them with square brackets like [Refugees Characteristic], [First Name], [Last Name], [Insurance Nr], [Marital status], [Nr of Children] etc. As a general purpose, if you have to use two words for your column names, you can write your works adjacent.
Also use using statement to dispose your OleDbConnection and OleDbCommand instead of calling their .Close() and .Dispose() methods manually.
using(var myconection = new OleDbConnection(ConnectionString))
using(var mycomand = myconection.CreateCommand())
{
//
}
And don't use AddWithValue method. It may generate upexpected results sometimes. Use .Add() overloads instead to specify your OleDbType and your parameter size.
As a final thing, Picture seems a form and report property in MS Access. That means it is a reserved word. You need to use it [Picture] as well.
Put your column names inside the square bracket.
[First Name],[Marital status],[Nr of Children],[Address],[Mother Tongue],[Other Languages],[Phone Nr]
So it would be like
mycomand.CommandText = #"INSERT INTO [Refugees Characteristic]([Nr],[First Name],[Last Name],[Birthday],[Country],[City],[Insurance Nr],[Gander],[Marital status],[Nr of Children],[Address],[Mother Tongue],[Other Languages],[Phone Nr],[Enter to Austria],[Education],[Skills],[Picture]) VALUES (#p1,#p2,#p3,#p4,#p5,#p6,#p7,#p8,#p9,#p10,#p11,#p12,#p13,#p14,#p15,#p16,#p17,#p18)";
Related
I'm making a form where a user answers some questions to make a pricehold. My problem is I can't store the data from the questions into more than one sql table.
I have tried inserting the other table into the sql command (shown below) and I have tried making another sql command that basically says the same thing with a different name but splitting the name and phone number into the first one and the date created and pick up date into the second one but that only runs the first sql command and then stops so data is never stored into the second table
private void AddPhBttn_Click(object sender, RoutedEventArgs e)
{
SqlConnection furniture = new SqlConnection("Data Source=LAPTOP-F4QFMPFD\\MSSQLSERVER1;Initial Catalog=Furniture;Integrated Security=True");
furniture.Open();
SqlCommand add = new SqlCommand("insert into Customers(Name, Phone) PriceHold(DateCreated, PickUpDate) values ('" + nameTxtBox.Text + "', '" + phoneTxtbox.Text + "', '" + dateTxtBox.Text + "', '" + puDateTxtBox.Text + "')", furniture);
int i = add.ExecuteNonQuery();
if (i != 0)
{
MessageBox.Show("saved");
}
else MessageBox.Show("error");
}
As #Caius Jard said, you can't do this with an ad-hoc query.
So what is an option to do so?
Step 1: Create a Stored Procedure in the Database:
CREATE PROCEDURE usp_InsertData
#Name NVARCHAR(200),
#Phone NVARCHAR(100),
#DateCreated Date,
#PickUpDate Date
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO Customers(Name, Phone) VALUES (#Name,#Phone)
INSERT INTO PriceHold(DateCreated, PickUpDate) VALUES (#DateCreated,#PickUpDate)
END
Step 2: Call above Stored procedure in C# Code:
private void AddPhBttn_Click(object sender, RoutedEventArgs e)
{
var furniture = new SqlConnection("Data Source=LAPTOP-F4QFMPFD\\MSSQLSERVER1;Initial Catalog=Furniture;Integrated Security=True");
SqlCommand add = new SqlCommand("usp_InsertData", furniture);
add.CommandType = System.Data.CommandType.StoredProcedure;
add.Parameters.AddWithValue("#Name", nameTxtBox.Text);
add.Parameters.AddWithValue("#Phone", phoneTxtbox.Text);
add.Parameters.AddWithValue("#DateCreated", dateTxtBox.Text);
add.Parameters.AddWithValue("#PickUpDate", puDateTxtBox.Text);
furniture.Open();
int i = add.ExecuteNonQuery();
if (i != 0)
{
MessageBox.Show("saved");
}
else
{
MessageBox.Show("error");
}
furniture.Dispose();
}
You can't do this in SQL
INSERT INTO
myfirsttable(column1, column2)
mysecondtable(column3, column4, column5)
VALUES(value1, value2, value3, value4)
It's flat out a syntax error. Only one table may appear in an insert. The number of values inserted must match the number of columns
If you want to insert into two tables, run two separate inserts from your c# code
Finally, have a long read of http://bobby-tables.com - your code is currently highly insecure and while this may not matter right now because it's just some small test app, it is best to avoid embarking on a learning path that includes coding in this way. As a recruiter I've turned down many job candidates who have written SQL like this and I'd never employ someone who demonstrated this style to me
When working with data in more than one table, if you want to ensure either all insert/update/delete complete successfully or none of them are applied on your data to ensure data integrity, use transactions. I think SqlTransaction is what you're after. Read about it here.
For your specific case, this is one possibility:
private void AddPhBttn_Click(object sender, RoutedEventArgs e)
{
// Necessary input validation to collect and data from input fields. Good practice to avoid SQL injection.
AddFurniture(nameTxtBox.Text, phoneTxtbox.Text, dateTxtBox.Text, puDateTxtBox.Text);
}
private void AddFurniture(string name, string phoneNumber, string createdDate, string pickupDate)
{
string connectionString = "Data Source=LAPTOP-F4QFMPFD\\MSSQLSERVER1;Initial Catalog=Furniture;Integrated Security=True"; // This should ideally come from some configuration.
using(SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction = connection.BeginTransaction("Add Furniture");
command.Connection = connection;
command.Transaction = transaction;
try
{
connection.Open();
command.CommandText = $"insert into Customers (Name, Phone) values ({name}, {phoneNumber});";
command.ExecuteNonQuery();
command.CommandText = $"insert into PriceHold (DateCreated, PickUpDate) values ({createdDate}, {pickupDate});";
command.ExecuteNonQuery();
// Try to commit to database.
// Both the above queries are executed at this point. If any one of them fails, 'transaction' will throw an exception.
transaction.Commit();
}
catch (Exception ex1)
{
// Considering the statements executed using the 'transaction' for this 'connection',
// one of the insert operations have clearly failed.
// Attempt to roll back the change which was applied.
MessageBox.Show($"Insert failed. Trying to roll back {ex1.Message}");
try
{
transaction.RollBack();
}
catch (Exception ex2)
{
// Rollback also failed. Possible data integrity issue. Handle it in your application.
MessageBox.Show($"Roll back failed. {ex2.Message}");
}
}
}
}
This code is supposed to save some values in textboxes to a specific row. The code runs just fine with no hiccups, but refuses to actually update the database no matter what I do.
try
{
using (var con = new OleDbConnection())
{
con.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\User\Desktop\esoft\gym\gym\bin\Debug\Clients.accdb;";
con.Open();
using (var com = new OleDbCommand())
{
com.Connection = con;
com.CommandText = "UPDATE gym SET BMI = #bmi and Health = #health and weight_change_to_healthy_bmi = #weight WHERE ID = #id";
com.Parameters.AddWithValue("#bmi", bmi.Text);
com.Parameters.AddWithValue("#health", health.Text);
com.Parameters.AddWithValue("#weight", change.Text);
com.Parameters.AddWithValue("#id", id.Text);
com.ExecuteNonQuery();
}
}
MessageBox.Show("Saved");
}
catch (Exception ex)
{
MessageBox.Show("Not saved: " + ex.Message);
}
Any help would be much appreciated.
As Alex mentioned, SET part needs , instead of AND for multiple columns.
Check UPDATE syntax1;
UPDATE table_name
SET column1=value1,column2=value2,...
WHERE some_column=some_value;
But I wanna say a few things more;
Don't use AddWithValue as much as you can. It may generate unexpected and surprising results sometimes. Use Add method overload to specify your parameter type and it's size.
Open your connection just before you execute your command. That means, you should open your connection just before your ExecuteNonQuery line.
Based on it's name, ID column should be some numeric value instead of character. Consider to change it's type or consider to change it's column name that refers some character typed column name.
1: I know I know.. a w3school link
I wonder if someone could help me with this SQL insert query? I've a nasty suspicion that I am staring at something very obvious, but I've been trying to figure it out for a while now, and I can't see what's wrong. At the moment it just drops through to the catch loop when I try and execute. I'm using Visual studio Community 2015. Incidentally, is there anywhere in VS where you can try out a SQL statement?
Here's the code
private void button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection myConnection = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = ""C:\Users\Nick\Documents\Investments 4.mdf""; Integrated Security = True; Connect Timeout = 30");
myConnection.Open();
if (myConnection.State == ConnectionState.Open)
{
MessageBox.Show("Connection Open");
}
SqlCommand myCommand3 = new SqlCommand();
myCommand3.CommandType = System.Data.CommandType.Text;
myCommand3.CommandText = "INSERT INTO Dbo.Values (Portfolio Name,Date,Daily Value,Daily Percent) VALUES ('Ascentric',#SQLTime,2000,0.01)";
//myCommand.Parameters.Add("#SQLPortName", System.Data.SqlDbType.NVarChar);
//myCommand.Parameters["#SQLPortName"].Value = "Eric";
myCommand3.Parameters.Add("#SQLTime", System.Data.SqlDbType.DateTime );
myCommand3.Parameters["#SQLTime"].Value = DateTime.Today;
myCommand3.ExecuteNonQuery();
myConnection.Close();
}
catch
{
MessageBox.Show("Nope. Didn't work");
}
}
And here's the table:
By the way, I do understand that I need to parameterise this, but I am just trying to get the basic statement to work at the moment.
Any help gratefully received!
You have to wrap your column names in brackets if they include spaces, or are a reserved keyword (such as Date):
myCommand3.CommandText = "INSERT INTO Dbo.Values ([Portfolio Name],[Date],[Daily Value],[Daily Percent]) VALUES ('Ascentric',#SQLTime,2000,0.01)";
As a best practice: Don't ever use spaces in SQL for objects (columns, SPROCS, etc). Use CamelCase or underscores_to_separate_words. Because you'll forget the brackets again one day.
Creating columns with Space is not the best practice to follow. First remove spaces and make your columns as single word. If you want to show spaces at the time of selection you may use alias instead.
myCommand3.CommandText = "INSERT INTO dbo.Values (PortfolioName,[Date],DailyValue,DailyPercent) VALUES ('Ascentric',#SQLTime,2000,0.01)";
myCommand3.Parameters.Add(new SqlParameter("#SQLTime",DateTime.Today.ToString());
private void btnID_Click(object sender, EventArgs e)
{
//Set Up Conncetion
SqlConnection myconnection = new SqlConnection(global::Database_connection_inForm.Properties.Settings.Default.Database1ConnectionString);
try
{
string sql = "INSERT INTO Students(Student ID,Student Name) values("+txtID.Text+",'"+txtName.Text+"')";
//Command object
SqlCommand exeSql = new SqlCommand(sql, myconnection);
myconnection.Open(); //Opening connection
exeSql.ExecuteNonQuery();
MessageBox.Show("Add new Record Done!","Message",MessageBoxButtons.OK,MessageBoxIcon.Information);
this.studentsTableAdapter.Fill(this.database1DataSet.Students);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
myconnection.Close();
}
}
private void btnRef_Click(object sender, EventArgs e)
{
this.studentsTableAdapter.Fill(this.database1DataSet.Students);
}
}
When a column name contains spaces you should always encapsulate that name with square brackets
sql = "INSERT INTO Students([Student ID],[Student Name]) ....."
Said that, please remove your string concatenation and use a parameterized query ALWAYS.
It is far better to use parameters instead of string concat. The main reason is to avoid Sql Injection but the parameter approach will also remove the quoting problem (IE a name = 'O'Brian' leads to a syntax error when using string concat)
private void btnID_Click(object sender, EventArgs e)
{
try
{
string sql = "INSERT INTO Students([Student ID],[Student Name]) " +
"values (#id, #name)";
using(SqlConnection myconnection = new SqlConnection(....))
using(SqlCommand exeSql = new SqlCommand(sql, myconnection))
{
myconnection.Open();
exeSql.Parameters.AddWithValue("#id",Convert.ToInt32(txtID.Text));
exeSql.Parameters.AddWithValue("#name",txtName.Text);
exeSql.ExecuteNonQuery();
}
}
.....
Also notice that I have converted the txtID.Text contents to an integer without any checking.
This could fail if your user types something that is not a valid numeric id (And if the Student ID is an Identity column then this value should never be passed in the INSERT statement)
As a final note. Do you really need these columns names? It is far better to have them without spaces otherwise you will get this problem every time you use this table
If your identifiers contain spaces, you have to delimit the identifier. The way you do that depends on the database you are using.
In SQL Server you use Square brackets:
string sql = "INSERT INTO Students([Student ID],[Student Name]) values(#Id,#Name)";
In MySQL you use backticks:
string sql = "INSERT INTO Students(`Student ID`,`Student Name`) values(#Id,#Name)";
Note that I have replaced the concatenated values in the queries with parameters. You should use parameterised queries, otherwise your code is wide open to SQL injection attacks.
First of all you did not Use Correct naming convention
you should use
StudentId Or Student_Id ( the first one is recommended)
when you have space between you column Names you should use "[" "]" and cover your column name
You have a space in column name
string sql = "INSERT INTO Students(Student ID,Student Name) values("+txtID.Text+",'"+txtName.Text+"')";
thats a problem - check a column name and use a right column name.
I have a SqlCommand that attempts to insert a row in a SQL Server database table. The column of interest is a nvarchar(100) and the data that needs to be input will include characters such as "-", ";" and "\". When I insert a string without these characters everything works fine. When I attempt to insert a string that includes these characters the code fails because these characters are literally understood by the code and thus reports a syntax error. I have resolved such an issue in TSQL alone using dynamic sql, however I cannot find any good references to perform this action in C#. I suppose I could create a stored procedure and pass the values, but is there a way in which I could efficiently perform this using C# alone? If so, How? Or is passing values to a Stored Procedure a better approach?
Here is a simplified version of the code:
String SQLServerInstanceNames = "ussqlclus-db43\ussqlclusdb43; ussqlclus-db44\ussqltrysdb44; ussqltrys-db45\ussqltrysdb45;"
//Create Connection (Get Connection string from Server Explorer)
SqlConnection myConnection = new SqlConnection("Data Source=SERVER1;Initial Catalog=Database1;Integrated Security=True");
//Open connection
try { myConnection.Open(); }
catch (Exception e) { Console.WriteLine(e.ToString()); }
SqlCommand myCommand = new SqlCommand("INSERT INTO [dbo].[Table1]" +
"([SQLServerInstanceNames])" +
"VALUES (SQLServerInstanceNames);", myConnection);
//Execute command
myCommand.ExecuteNonQuery();
//Close connection
try { myConnection.Close(); }
catch (Exception e) { Console.WriteLine(e.ToString()); }
Try with SqlParameters. It will save you from Sql Injection as well as from your current problem.
myCommand.Parameters.AddWithValue("#param1", myValueWithCharacters);
C# uses \ as a control character. You can ignore those by prepending the string with an # character:
String SQLServerInstanceNames = #"ussqlclus-db43\ussqlclusdb43; ussqlclus-db44\ussqltrysdb44; ussqltrys-db45\ussqltrysdb45;"
Just update your code like this to include parmeters in INSERT statement
SqlCommand myCommand = new SqlCommand("INSERT INTO [dbo].[Table1]" +
"([SQLServerInstanceNames])" + "VALUES (#SQLServerInstanceNames);", myConnection);
myCommand.Parameters.AddWithValue("#SQLServerInstanceNames", "instance name");
Notice I updated VALUES part and added #SQLServerInstanceNames – this is how you add parameters to your query.
Now that you use parameters you won’t have to worry about special characters. These will be handled automatically.