"Number of query values and destination fields are not the same" - c#

try
{
connection.Open();
OleDbCommand komanda = new OleDbCommand();
command.Connection = konekcija;
command.CommandText = "insert into EmployeeData (FirstName,LastName,Pay) values('"+txt_fname.Text+"','"+txt_lname.Text+"','"+txt_pay.Text+"')";
command.ExecuteNonQuery();
MessageBox.Show("data saved");
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show("error"+ex);
}

The root of the problem is that you don't actually know what query you're executing. Because you're executing any code that your users send you.
In most non-edge cases this appears to "work just fine" (which is why it often goes unnoticed), in some cases it causes a syntax or structural error in the query (which is what's happening here), and in some cases users take advantage of it to execute arbitrary code on your database.
This is called a SQL injection vulnerability.
You'd correct this by using query parameters which treat user input as values instead of as executable code. Something like this:
command.CommandText = "insert into EmployeeData (FirstName,LastName,Pay) values(?,?,?)";
command.Parameters.Add("#FirstName", OleDbType.VarChar, 50).Value = txt_fname.Text;
command.Parameters.Add("#LastName", OleDbType.VarChar, 50).Value = txt_lname.Text;
command.Parameters.Add("#Pay", OleDbType.VarChar, 50).Value = txt_pay.Text;
command.ExecuteNonQuery();
Note that I've guessed on the OleDbType and size of the columns. Adjust as necessary for your table structure.

Related

How to update ms access database with parameters c#

I am trying to update my ms access db with windows application and I am having a hard time. When I run it I don't get any errors but it does update like once or twice when I test it but then doesn't work again if I do it again a third time.
This is the code I use
Conn.Open();
Command.CommandType = CommandType.Text;
Command.CommandText ="UPDATE TABLE SET c_qty=#qty WHERE id = #ID";
Command.Parameters.AddWithValue("#qty", txtQty.Text);
Command.Parameters.AddWithValue("#ID", txtID.Text);
Command.ExecuteNonQuery();
Conn.Close();
I felt I was doing this right or on the right track of having it correct but seems to be more of a issue then I thought. Any help would be great
Quantity and Id are hopefully integers and you should pass them as such.
Also Table is a reserved word, if this really is the name of your table you should enclose it with square brackets.
You should also pass in the correct db types in your parameters and not use AddWithvalue which does not allow this.
Code
Conn.Open();
Command.CommandType = CommandType.Text;
Command.CommandText ="UPDATE [TABLE] SET c_qty= ? WHERE id = ?";
Command.Parameters.Add(new OleDbParameter("#qty", OleDbType.Int) {Value = int.Parse(txtQty.Text)});
Command.Parameters.Add(new OleDbParameter("#ID", OleDbType.Int) {Value = int.Parse(txtID.Text)});
var rowsUpdated = Command.ExecuteNonQuery();
// output rowsUpdated to the log, should be 1 if id is the PK
Conn.Close();
Finally use using blocks for your Disposables. If you were to get an Exception here then connection would remain open until Garbage collection runs which means you might have a problem with other connection attempts to this Access database.
Revised with using blocks
using (OleDbConnection Conn = new OleDbConnection("connectionStringHere"))
using (OleDbCommand Command = new OleDbCommand("UPDATE [TABLE] SET c_qty= ? WHERE id = ?", Conn))
{
Command.Parameters.Add(new OleDbParameter("#qty", OleDbType.Int) {Value = int.Parse(txtQty.Text)});
Command.Parameters.Add(new OleDbParameter("#ID", OleDbType.Int) {Value = int.Parse(txtID.Text)});
Conn.Open();
var rowsUpdated = Command.ExecuteNonQuery();
// output rowsUpdated to the log, should be 1 if id is the PK
}
Finally OleDbCommand does not support named parameters, see OleDbCommand.Parameters

OleDB update command not changing data

I'm using Microsoft Access file as database. I have no problem with SELECT and INSERT queries but when I try to UPDATE, record in database does not change.
Below is the code I use to run update. There are no exceptions or errors in debug log.
cnn = new OleDbConnection(connetionString);
OleDbCommand command = new OleDbCommand("UPDATE [Wpisy] SET [wpis]=#wpis, [id_kat]=#id_kat, [tytul]=#tytul WHERE [ID]=#id_wpis" , cnn);
command.Parameters.Add(new OleDbParameter("#wpis", tresc_wpisu.Text));
command.Parameters.Add(new OleDbParameter("#id_kat", lista_kategorii.SelectedValue));
command.Parameters.Add(new OleDbParameter("#tytul", tytul_wpisu.Text));
command.Parameters.Add(new OleDbParameter("#id_wpis", Request["id"].ToString() ));
command.Connection = cnn;
try
{
if(cnn.State.ToString() != "Open")
cnn.Open();
command.ExecuteNonQuery();
cnn.Close();
}
catch (OleDbException ex)
{
Response.Clear();
Response.Write(ex);
Response.End();
}
I would go to Microsoft Access and enter the command there and see what happens. It should tell you how many rows was affected. If it says zero rows, then break your query into smaller pieces, such as:
select * where [ID]=value
And then you should be able to track down where the problem is.
I know this isn't an exact answer, but there are some quirks with working with MS Access.
Here is an example method for you with some proper exception handling for databases. For Object, create a class that represents a row fields in your table. I use Exception ex instead of the db library exception since I use DataReaders for selects.
private String connectionString = "someOleDbConnectionString";
public String UpdateObject(Object obj)
{
OleDbConnection connection = GetMyOleDbConnection(); //returns new OleDbConnection with proper connection string
String updateSql = "UPDATE [Wpisy] SET [wpis]=#wpis, [id_kat]=#id_kat, [tytul]=#tytul WHERE [ID]=#id_wpis";
OleDbCommand command = new OleDbCommand(updateSql, connection);
command.CommandType = System.Data.CommandType.Text; //this can be changed if you have stored procedures in your db.
//you may have to define the OleDbType of the parameter being defined
command.Parameters.Add(new OleDbParameter("#wpis", OleDbType.VarChar, obj.tresc_wpisu));
command.Parameters.Add(new OleDbParameter("#id_kat", OleDbType.VarChar, obj.lista_kategorii));
command.Parameters.Add(new OleDbParameter("#tytul", OleDbType.VarChar, obj.tytul_wpisu));
command.Parameters.Add(new OleDbParameter("#id_wpis", OleDbType.Integer, obj.id.ToString()));
return Execute(connection, command);
}
private OleDbConnection GetMyOleDbConnection()
{
return new OleDbConnection(connectionString);
}
private String Execute(OleDbConnection connection, OleDbCommand command)
{
try
{
connection.Open();
command.ExecuteNonQuery();
//I also know with Access databases,
//sometimes you have to close the table if it is open in MS Access
connection.Close();
return "SUCCESS";
}
catch (Exception ex)
{
connection.Close(); //important or you will have left open connections
Response.Clear();
Response.Write(ex.Message);
Response.End();
return ex.Message;
}
}
I could be wrong, but from what I remember, OleDB doesn't allow named parameters, but instead use "?" as a place-holder, and the parameters need to be added in the same sequence as they appear in the SQL statement. such as
String updateSql = "UPDATE [Wpisy] SET [wpis]=?, [id_kat]=?, [tytul]=? WHERE [ID]=?";
command.Parameters.Add(new OleDbParameter("parm_wpis", OleDbType.VarChar, obj.tresc_wpisu));
command.Parameters.Add(new OleDbParameter("parm_id_kat", OleDbType.VarChar, obj.lista_kategorii));
command.Parameters.Add(new OleDbParameter("parm_tytul", OleDbType.VarChar, obj.tytul_wpisu));
command.Parameters.Add(new OleDbParameter("parm_id_wpis", OleDbType.Integer, obj.id.ToString()));
Naming the parameters is just for clarification to know which is which. One other issue might be that you named the parameters by the same name as the column being updated, and that may have been the issue almost like a constant...
set X = X instead of now set X = parmX... there is no ambiguity the you are setting to the PARAMETER value being applied. But overall, I do think it will work via using "?" as the parameter place-holder.

C# ADO.NET - Could Not Find Stored Procedure

I am trying to execute a stored procedure through C#, ADO.NET and below is the code I am trying to execute:
using (SqlConnection conn = new SqlConnection(".;Initial Catalog=MyDB;User ID=sa;Password=***"))
{
try
{
string cmdText = "dbo.sp_Create_FlaggedItemEntry #URI, #ID";
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
conn.Open();
cmd.CommandText = cmdText;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#URI", value1);
cmd.Parameters.AddWithValue("#ID", value2);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (conn != null)
{
conn.Close();
}
}
}
Now when I try to debug it, I got an error at the line - cmd.ExecuteNonQuery(); - "Could Not Find Stored Procedure dbo.sp_Create_FlaggedItemEntry"
I verified that the Connection String is all correct and Stored Procedure exists.
Further, If I change the line - cmd.CommandType = CommandType.StoredProcedure; to cmd.CommandType = CommandType.Text; it get executed successfully and as expected.
Can someone suggest what I am missing and doing wrong here - Please pardon me if it is something very basic as it is quite long since I last worked with ADO.NET
CommandType.StoredProcedure means that the CommandText should only contain the name of the stored procedure.
Remove the parameter names from the string.
Take the parameters out of the command text. Also, you don't need to specify dbo.
The reason it's working with CommandType.Text is because it's a legitimate SQL command like that - if you were to open up SSMS and type that in it'd work as long as you also create the variables #URI and #ID
Documentation here
You should mention Data Source / Server in connectionString. Also for CommandText #Slaks is correct.

SqlCeCommand Parameters not working

I have a SQL Server Compact database and I'm trying to insert a record into it using cmd.ExecuteNonQuery(). This method worked perfectly fine in another project, but it doesn't work now.
private void AddNewProfile() {
try {
using(SqlCeConnection conn = new SqlCeConnection(Properties.Settings.Default.dbConnectionString)) {
using(SqlCeCommand cmd = new SqlCeCommand()) {
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription) VALUES ('#name', '#path', '#desc');";
cmd.Parameters.AddWithValue("#name", SqlDbType.Text).Value = "New Profile";
cmd.Parameters.AddWithValue("#path", SqlDbType.Text).Value = "C:\\";
cmd.Parameters.AddWithValue("#desc", SqlDbType.Text).Value = "A blank profile.";
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
}
catch(Exception ex) {
MessageBox.Show(ex.Message, "Error");
}
}
The problem comes in with the parameters - I practically copied the code from one of my other projects, but it doesn't work correctly. Instead of executing this:
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES ('New Profile', 'C:\\', 'A blank profile.');
it executes this:
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES ('#name', '#path', '#desc');
What is the problem here?
Two problems:
Firstly, your SQL is specifying literal values because of the quotes. It should be:
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES (#name, #path, #desc)
That way the SQL refers to the parameters, rather than literals with values of `"#name", "#path" and "#desc".
(I've removed the unnecessary semi-colon as well.)
Secondly, calling AddWithValue, but providing the type as the value, then overwriting the value. That's pointless and confusing - the type you're specifying is going to be lost. You should be using:
cmd.Parameters.Add("#name", SqlDbType.Text).Value = "New Profile";
Finally, you don't need to call conn.Close() - it's already in a using statement... and you can pass conn to the SqlCeCommand constructor, to make things slightly simpler.
You don't need to use single quotes when you declare your parameters. With single quotes, SQL will recognize them as a string literal not parameters. Just use them in your SqlCommand like;
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES (#name, #path, #desc)
Also you are using AddWithValue in a wrong way. It doesn't need the type.
cmd.Parameters.AddWithValue("#name", "New Profile");
cmd.Parameters.AddWithValue("#path", "C:\\");
cmd.Parameters.AddWithValue("#desc", "A blank profile.");
or you can use Add if you want to declare their types like;
cmd.Parameters.Add("#name", SqlDbType.Text).Value = "New Profile";
cmd.Parameters.Add("#path", SqlDbType.Text).Value = "C:\\";
cmd.Parameters.Add("#desc", SqlDbType.Text).Value = "A blank profile.");
And your conn.Close(); is redundant. The using statement will take care of it for you. Under the hood, SqlConnection.Dispose() calls the SqlConnection.Close() method.
Problem 1: You are enclosig the parameters (#name, #path, #desc) within single quotes, so that you are passing the values as #name, #path, #desc .
Solution 1: You should not enclose the Parameters within single quotes while using Parameterised queries.
Replace This:
cmd.CommandText = "INSERT INTO Profiles (ProfileName, ProfilePath,
ProfileDescription) VALUES ('#name', '#path', '#desc');";
With This:
cmd.CommandText = "INSERT INTO Profiles
(ProfileName, ProfilePath, ProfileDescription)
VALUES (#name, #path, #desc);";
Problem 2: you need to provide both parameter name and its value to the Parameters.AddWithValue() method
Solution 2:
Replace This:
cmd.Parameters.AddWithValue("#name", SqlDbType.Text).Value = "New Profile";
cmd.Parameters.AddWithValue("#path", SqlDbType.Text).Value = "C:\\";
cmd.Parameters.AddWithValue("#desc", SqlDbType.Text).Value = "A blank profile.";
With This:
cmd.Parameters.AddWithValue("#name","New Profile");
cmd.Parameters.AddWithValue("#path","C:\\");
cmd.Parameters.AddWithValue("#desc","A blank profile.");
Complete Code:
private void AddNewProfile() {
try {
using(SqlCeConnection conn = new SqlCeConnection(Properties.Settings.Default.dbConnectionString)) {
using(SqlCeCommand cmd = new SqlCeCommand()) {
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO Profiles (ProfileName, ProfilePath,
ProfileDescription) VALUES (#name,#path, #desc);";
cmd.Parameters.AddWithValue("#name","New Profile");
cmd.Parameters.AddWithValue("#path","C:\\");
cmd.Parameters.AddWithValue("#desc","A blank profile.");
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
catch(Exception ex) {
MessageBox.Show(ex.Message, "Error");
}
}

Question in error in asp.net c#

i have a question if you please help me i have an error
Must declare the scalar variable
"#Deitails".
and i can not find out whats the problem since i am not aware what Scalar is about
var sqlCon = new
SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
// GET CONFERENCE ROLE ID
SqlCommand cmd = new SqlCommand();
cmd.Connection = sqlCon;
cmd.CommandText = "select Conference_Role_ID from AuthorPaper
where Paper_ID = #PaperId";
cmd.Parameters.AddWithValue("#PaperId",
paperId);
cmd.Connection.Open();
string ConferenceRoleId = cmd.ExecuteScalar().ToString();
cmd.Connection.Close();
cmd.Dispose();
string query2 = #"insert into
ReviewPaper(Overall_Rating,Paper_id,Conference_role_id,Deitails)
values(0,#paperId,#ConferenceRoleId,#Deitails);select
SCOPE_IDENTITY() as RPID";
cmd = new SqlCommand(query2, sqlCon);
cmd.Parameters.AddWithValue("#paperId",
paperId);
cmd.Parameters.AddWithValue("#ConferenceRoleId",
ConferenceRoleId);
string ReviewPaperId;
try
{
cmd.Connection.Open();
ReviewPaperId = cmd.ExecuteScalar().ToString();
cmd.Connection.Close();
}
catch (Exception ee) { throw ee; }
finally { cmd.Dispose(); }
thanks
You have a SQL query with a parameter named Details, but you forgot to add the parameter.
You have a line of code which says
string query2 = #"insert into ReviewPaper(Overall_Rating, Paper_id,
Conference_role_id, Deitails) values (0,#paperId,#ConferenceRoleId,#Deitails);
select SCOPE_IDENTITY() as RPID";
You provide the parameters #paperId, #ConferenceRoleId and #Deitails for the values for the insert statement. Later you specify the value for the first two parameters, but not #Deitails:
cmd.Parameters.AddWithValue("#paperId", paperId);
cmd.Parameters.AddWithValue("#ConferenceRoleId", ConferenceRoleId);
You need to add a similar line to add the value for #Deitails so that SQL server knows what to do with it. The error you are getting is coming from SQL server because by not adding a value for #Deitails in your C# code, it is not being declared for you in the SQL code which is sent to the server.
To answer your other question, 'Scalar' in this case means that the variable #Deitails represents a single value.

Categories

Resources