private void button1_Click(object sender, EventArgs e)
{
string tablename = label2.Text;
string name = TextBox1.Text;
DBconnection.savetodb(tablename, name);
}
I call the method below from another form to save the name into a specific table. But it wont save into my table in database.
public static void savetodb(string tablename, string name)
{
OleDbConnection connection = GetConnection();
string query = String.Format("INSERT INTO {0} (Name) VALUES (#Name)", tablename);
OleDbCommand cmd = new OleDbCommand(query, connection);
cmd.Parameters.AddWithValue("#Name", name);
try{
connection.Open();
cmd.ExecuteNonQuery();
}
catch (Exception ex){
Console.WriteLine("Exception catch", ex);
}
finally{
myConnection.Close();
}
Thanks for help.
You are not passing table name as a parameter, you are passing your #Name value as a parameter. You can't pass a table name as a parameter even if you want. Parameters only for values, not table or column names. You are just formatting your query based table name. As far as I see, your problem using named parameters. OleDb provider does not support named parameters.
From OleDbCommand.Parameters
The OLE DB .NET Provider does not support named parameters for passing
parameters to an SQL statement or a stored procedure called by an
OleDbCommand when CommandType is set to Text. In this case, the
question mark (?) placeholder must be used. For example:
SELECT * FROM Customers WHERE CustomerID = ?
Therefore, the order in which OleDbParameter objects are added to the
OleDbParameterCollection must directly correspond to the position of
the question mark placeholder for the parameter in the command text.
Try it as;
string query = String.Format("INSERT INTO {0} (Name) VALUES (?)", tablename);
...
cmd.Parameters.AddWithValue("#name", name);
Also use using statement to dispose your OleDbConnection and OleDbCommand.
using(OleDbConnection connection = new GetConnection())
using(OleDbCommand cmd = con.CreateCommand())
{
}
And consider to use .Add method instead .AddWithValue. It may cause some problems. Read Can we stop using AddWithValue() already?
Related
To test SQLite I created a very simple SQLite DB (Verion 3) with one Table and two columns (ID int, UserInput TEXT)... ID is auto increment.
I want to insert a value from a user input which is a text box however when I check the returned CommandText the parameter is not replaced but remains as "(#paramInput)"
private void button1_Click(object sender, RibbonControlEventArgs e)
{
using (SQLiteConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
string strValue = editBox1.Text;
SQLiteCommand cmd = cnn.CreateCommand();
cmd.CommandText = "insert into main.TestTable (UserInput) values (#paramInput)";
//replace #paramInput by using AddWithValue
cmd.Parameters.AddWithValue("#paramInput", strValue);
//check result before
MessageBox.Show(cmd.CommandText);
//write to DB
cnn.Execute(cmd.CommandText);
}
}
I have also tried using Parameters.Add:
//replace #paramInput by using Add
cmd.Parameters.Add("#paramInput", DbType.String);
cmd.Parameters[0].Value = strValue;
but again the CommandText remains as:
"insert into main.TestTable (UserInput) values (#paramInput)"
obviously resulting in error message "error Insufficient parameters supplied" when sent to the DB.
What am I missing? I've looked at various examples and they seem all to fill the parameters either by AddWithValue or Parameters.Add. Sure I could use C# parameters on the query but at least out of curiosity would like to understand what I do wrong.
System.Data.SQLite.Core 1.0.116
I would prefer to call cmd.ExecuteNonQuery(); instead of cnn.Execute(cmd.CommandText); because you trying to execute the text you set to cmd.CommandText "insert into main.TestTable (UserInput) values (#paramInput)" and parameter has not been replaced by the real value.
using (SQLiteConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
string strValue = editBox1.Text;
SQLiteCommand cmd = cnn.CreateCommand();
cmd.CommandText = "insert into main.TestTable (UserInput) values (#paramInput)";
//replace #paramInput by using AddWithValue
cmd.Parameters.AddWithValue("#paramInput", strValue);
//check result before
MessageBox.Show(cmd.CommandText);
//write to DB
cmd.ExecuteNonQuery();
}
I am trying to work with a contact list and want to remove all of the info on a person when I type in their name. I am using a sql table -named Contact- that contains the Name, Email and Address of a contact. I have the following code:
protected void Delete_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnect"].ConnectionString);
con.Open();
string delete = "DELETE FROM Contact WHERE Name =" + NameToDelete.Text;
SqlCommand cmd = new SqlCommand(delete, con);
try
{
cmd.Parameters.AddWithValue("#Name", delete);
cmd.ExecuteNonQuery();
Response.Redirect("ViewContacts.aspx");
}
catch(Exception ex)
{
Response.Write(ex);
}
}
When I use this, it seems to be comparing the column Name to the name I am putting in. So the name Bill is being compared against the column header Name instead of what is in the name.
You need to use single quotes around the values with var(char) types. If you don't use quotes it will think that you are referencing a column name instead of value.
It's valid for all databases, following is from oracle docs:
character literals are enclosed in single quotation marks, which
enable Oracle to distinguish them from schema object names.
https://docs.oracle.com/cd/A87860_01/doc/server.817/a85397/sql_elem.htm
string delete = "DELETE FROM Contact WHERE Name ='" + NameToDelete.Text + "'";
Actually what you are trying to do is using sqlcommand parameter, then you need to use parameter name using #[ParameterName] in sql statement.
string delete = "DELETE FROM Contact WHERE Name = #Name";
Seems that your problem is that you are using the variable delete in two instances. First for create the command that is fine and second as the parameter value, which is wrong. In the parameter value probably you must use the value tthat you want to delete.
You have several serious problems with your code.
Your connection is never closed or disposed. Use Using blocks which will close and dispose of database objects even if there is an error.
You are concatenating a string to get your Sql statement risking Sql injection and damage to your database.
You are adding a parameter to your command when there are no parameters in your Sql statement.
You are using .AddWithValue which takes the parameter name and the parameter value as arguments. You have provided your entire Sql statement as the value of #Name. This should be NameToDelete.Text.
Do not use .AddWithValue. Use .Add(parameter Name, Sql data type).Value = value of parameter. This can speed up queries and avoids type mismatches in the database.
If name is your Primary Key, you are OK, but if not you should delete by the primary key or send all values in the Where clause.
protected void Delete_Click(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnect"].ConnectionString))
{
string delete = "DELETE FROM Contact WHERE Name = #Name;"; //no single quotes to worry about
using (SqlCommand cmd = new SqlCommand(delete, con))
{
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = NameToDelete.Text; //just guessed at the VarChar - check your database for type
try
{
con.Open();
cmd.ExecuteNonQuery();
Response.Redirect("ViewContacts.aspx");
}
catch (Exception ex)
{
Response.Write(ex.Message); //ex by itself, will get you nothing but the fully qualified name of Exception
}
}
}
}
I have a problem with a MySql insert ... this is my Code:
public class struc
{
public string Product;
public string Underproduct;
public string Version;
}
static void DatabaseConection(List<struc> Data)
{
string connString = "right connection info";
string insertQuery = "Insert into freigabedaten (produktname,unterprodukt,version,freigabestatus) values (productInfo.Product,productInfo.Underproduct,productInfo.Version,'4')";
MySqlConnection conn = new MySqlConnection(connString);
conn.Open();
foreach (var productInfo in Data)
{
MySql.Data.MySqlClient.MySqlCommand Command = new MySql.Data.MySqlClient.MySqlCommand(insertQuery, conn);
try
{
Command.ExecuteNonQuery();
}
catch (Exception)
{
throw;
}
});
conn.Close();
}
But i get always the Exeption:
MySql.Data.MySqlClient.MySqlException: "Unknown column
'productInfo.Product' in 'field list'"
My Database table structure is:
Databasetablescreen
can someone help me please?
Seems that you're passing all INSERT query arguments as part of query string, not as reference to productInfo object which contains column names (which they're treated as table names instead).
Use a parameterized MySQL query like this:
string insertQuery = "Insert into freigabedaten (produktname,unterprodukt,version,freigabestatus) values (#produktname,#underprodukt,#version,'4')";
And then declare input parameters for MySqlCommand inside foreach loop before using ExecuteNonQuery method:
MySql.Data.MySqlClient.MySqlCommand Command = new MySql.Data.MySqlClient.MySqlCommand(insertQuery, conn);
Command.Parameters.AddWithValue("#produktname", productInfo.Product);
Command.Parameters.AddWithValue("#unterprodukt", productInfo.Underproduct);
Command.Parameters.AddWithValue("#version", productInfo.Version);
Command.ExecuteNonQuery();
What are you trying to do?
If productInfo is a C# Struct/Class you need to add the values manually to the Query string.
string insertQuery = "Insert into freigabedaten (produktname,unterprodukt,version,freigabestatus) values ('"+productInfo.Product+"','"+productInfo.Underproduct+"','"+productInfo.Version+"','4')";
If productInfo is another table you'll need to query these values beforehand.
I was just wondering if there is a way to execute a stored procedure with out naming the parameters. Meaning that C# resolves the parameters in the order they're declared within the stored procedure.
public static DataTable GetRelatedResources(string StoredProcedure, object[] Parameters)
{
var Results = new DataTable();
try
{
using (SqlConnection conn = new SqlConnection())
{
using (SqlCommand cmd = new SqlCommand(ConfigurationManager.ConnectionStrings["MK3Entities"].ConnectionString))
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = StoredProcedure;
if (Parameters!= null)
{
foreach(var Param in Parameters)
{
// I Want To Do something like this
cmd.Parameters.AddWithValue(Param);
}
}
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(Results);
}
}
}
catch (Exception ex)
{
MMSLogger.Instance.WriteToLog("Exception Executing Stored Procedure:" + ex.Message);
}
return Results;
}
Execute a command instead, and pass in parameters '#p1', '#p2' etc:
cmd.CommandType = CommandType.Text;
cmd.CommandText = 'exec ' + StoredProcedure;
int i=0;
string comma = ' ';
foreach(var Param in Parameters)
{
var paramName = String.Format("#P{0}", i);
cmd.CommandText += comma + paramName;
cmd.Parameters.AddWithValue(paramName, Param);
++i;
comma = ', ';
}
Be aware that AddwithValue is huge performance antipattern. See How Data Access Code Affects Database Performance
As per MSDN:
The ParameterName is specified in the form #paramname. You must set
ParameterName before executing a SqlCommand that relies on parameters.
Another MSDN article for SqlCommand:
Nameless, also called ordinal, parameters are not supported by the
.NET Framework Data Provider for SQL Server.
So answer is no, there is no way to execute a stored procedure without naming the parameters.
Do you mean some thing like derived parameter. This MSDN article gave an overview:
Parameters can also be derived from a stored procedure using the
DbCommandBuilder class. Both the SqlCommandBuilder and
OleDbCommandBuilder classes provide a static method, DeriveParameters,
which automatically populates the parameters collection of a command
object that uses parameter information from a stored procedure. Note
that DeriveParameters overwrites any existing parameter information
for the command.
A nother solution would be to get the parameter of the stored procedure from the sql-database and than set them in your code. But this need one extra query. To get the parameter use:
select * from dbo.parameters where specific_name='procedure-name'
But in any case, you have to use parameter-names.
when i hit the add button to insert a new book, i get an error at cmd.ExecuteNonQuery(); Syntax error in INSERT INTO statement. Am i missing anything?
protected void btnAddBook_Click(object sender, EventArgs e)
{
string connect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|Bookdb.accdb";
using (OleDbConnection conn = new OleDbConnection(connect))
{
OleDbCommand cmd = new OleDbCommand("INSERT INTO Books (Title, Author, Price, Edition) VALUES (#Title, #Author, #Price, #Edition)");
cmd.CommandType = CommandType.Text;
cmd.Connection = conn;
cmd.Parameters.AddWithValue("#Title", TextBox1.Text);
cmd.Parameters.AddWithValue("#Author", TextBox2.Text);
cmd.Parameters.AddWithValue("#Price", TextBox3.Text);
cmd.Parameters.AddWithValue("#Edition", TextBox4.Text);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
The only reason that I can find as a possible failure for your code is if the Price field is a numeric field in your database table. You are creating a parameter with AddWithValue and this method creates a parameter whose datatype is derived from the datatype of the value passed. You pass a string (TextBox3.Text) and so AddWithValue creates a string parameter.
You could try to force the AddWithValue to create a numeric parameter with
cmd.Parameters.AddWithValue("#Price", Convert.ToDecimal(TextBox3.Text));
(Of course assuming a decimal Price column)
Right before you call conn.Open(), you need to call cmd.Prepare(), so that all the parameters you set are actually loaded into the SQL statement.