C#, Razor
my code is:
#using (SqlConnection Praktikum2 = new SqlConnection("Data Source=Mark\\SQLEXPRESS;Initial Catalog=Connection;Integrated Security=True"))
{
using(connection)
{
SqlCommand command = new SqlCommand("SELECT KategoryID FROM Kategory WHERE Name = " + Request.Params["kategory"]);
connection.Open();
SqlDataReader reader = command.ExecuteReader(); //ERROR!!!
while (reader.Read())
{
string ID = reader["KategorieID"].ToString() ;
Console.WriteLine("ID = {0}", ID);
}
reader.Close();
};
}
i get an error that there's a wrong syntax near "=".
how can i solve this?
The problem is caused by the missing quotes around the value passed for your search. You could add a set of single quote before and after the value obtained by the Request but that would be a bigger error and the source of a problem called Sql Injection.
The only way to handle this is to use a parameter query
SqlCommand command = new SqlCommand(#"SELECT KategoryID FROM Kategory
WHERE Name = #name", connection);
command.Parameters.Add("#name", SqlDbType.NVarChar).Value = Request.Params["kategory"];
Also, as noted in another answer, your code seems to not have associated the connection to the command, I think that it is just a typo here because the error message in that case would be 'need an open connection'
You forgot to assign the connection to the command. So when you call ExecuteReader(), it does not know on which connection it should be executed.
You can assign the connection like this:
SqlCommand command = new SqlCommand(
"SELECT KategoryID FROM Kategory WHERE Name = " + Request.Params["kategory"],
connection); // provide connection as second parameter!
or use connection.CreateCommand() to create your command.
Second, you forgot the quotation marks around your string:
"SELECT KategoryID FROM Kategory WHERE Name = '" + Request.Params["kategory"] + "'"
but inserting user data directly into your query opens your code to SQL Injection. Please use parameterized queries instead.
If your kategory column is not of integer data type then you need to surround your value with (') i.e single quote characters
Then your query will be like
SqlCommand command = new SqlCommand("SELECT KategoryID FROM Kategory WHERE Name ='" + Request.Params["kategory"] + "'");
The exception is caused by how you are creating your sql statement. The fix should not be correcting the syntax but using parameters instead. This will prevent sql injection attacks.
Also
You really should not be writting sql in your views, do it in your controller method instead and return the result in the Model to be used in your view. Better yet, abstract it to a different layer and call that layer from your controller. This has to do with SoS (Separation of Concerns), your code will very difficult to maintain if you just write everything into your views.
Wrap your connections, commands, and readers in using blocks.
Modified Code
#{
using(SqlConnection Praktikum2 = new SqlConnection("Data Source=Mark\\SQLEXPRESS;Initial Catalog=Connection;Integrated Security=True"))
using(SqlCommand command = new SqlCommand("SELECT KategoryID FROM Kategory WHERE Name = #name", Praktikum2))
{
command.Parameters.Add(new SqlParameter("#name", SqlDbType.VarChar){ Value = Request.Params["kategory"]});
connection.Open();
using(SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
string ID = reader["KategorieID"].ToString() ;
Console.WriteLine("ID = {0}", ID);
}
}
}
}
Related
Every time I execute a DELETE query on my database, the following error results:
No value given for one or more required parameters
I check the names but still have the error. Below is the code used to execute the query:
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
string query = "delete FROM Accounts WHERE Id_No = " + IdNoBox.Text + "";
command.CommandText = query;
command.ExecuteNonQuery();
MessageBox.Show("Successfully Deleted");
this.Close();
connection.Close();
Assuming Id_No to be string, it should be enclosed in single quotes.Otherwise, it will be considered as a parameter.
the query should string query = "delete FROM Accounts WHERE Id_No = "'" + IdNoBox.Text + "'";
To address the specific question being asked, if Id_No is a character based, there should be single quotes around it. For readability, consider the following syntax.
string query = string.Format("delete FROM Accounts WHERE Id_No = '{0}' ", IdNoBox.Text);
Also note that the connection/command should be disposed of properly, including the cases where an exception occurs. An easy way to do this is with the using clause. See below.
using (var connection = new OleDbConnection())
using (var command = new OleDbCommand(){Connection = connection,CommandText = query})
{
connection.Open();
command.ExecuteNonQuery();
}
MessageBox.Show("Successfully Deleted");
How can I add a variable to my SQL string and run it against the server successfully? I want to run this statement through my C#
protected void RunSQLQuery(string salesman, string connectionString)
{
SqlConnection cnn;
SqlCommand cmd;
StringBuilder sql = new StringBuilder();
SqlDataReader reader;
cnn = new SqlConnection(connectionString);
sql = new StringBuilder();
sql.Append("update database ");
sql.Append("set shippdate = GetDate() ");
sql.Append("where salesman = "' + salesman + "'");
sql.Append("and managerapproval is not null ");
cnn.Open();
cmd = new SqlCommand(sql.ToString(), cnn);
reader = cmd.ExecuteReader();
reader.Close();
cmd.Dispose();
cnn.Close
}
This presents multiple compile errors underlining my +salesman+ code. The errors are:
Only assignment, call, increment, decrement, and new object
expressions can be used as a statement
; expected
) expected
Too many characters in character literal Newline in constant
You are not adding the string object that salesman refers, you are adding salesman as a string literal.
Just add it as a parameter like;
var cmd = new SqlCommand("update database set shippdate = GetDate() where salesman = #salesman");
cmd.Parameters.Add("#salesman", salesman);
...
And use ExecuteNonQuery to execute your command, not SqlDataReader. This SqlDataReader is for return some data.
But more important, you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Also use using statement to dispose your connection and command automatically instead of calling Close or Dispose methods manually.
As a full example;
protected void RunSQLQuery(string salesman, string connectionString)
{
using(var cnn = new SqlConnection(connectionString))
using(var cmd = cnn.CreateCommand())
{
cmd.CommandText = #"update database set shippdate = GetDate()
where salesman = #salesman";
// I assume your column is nvarchar
cmd.Parameters.Add("#salesman", SqlDbType.NVarChar).Value = salesman;
cnn.Open();
cmd.ExecuteNonQuery();
}
}
For myself, I always prefer to use SqlParameterCollection.Add(string, SqlDbType, Int32) overload to specify my parameter type and it's size but since you never mentioned your salesman column type, I couldn't post this in my example.
As you can also see from the syntax highlighting, the compile errors are caused because you did not escape the quotes properly in sql.Append("where salesman = "' + salesman + "'");.
As a side note, you should never insert strings into sql queries without first validating them, or you are open to sql injection, e.g. if i pass "''; drop table database;" as salesman parameter. It is better to use SqlParameter.
I would suggest using the AddWithValue method from your sql command combined with the UPPER function to make it case insensitive:
SqlCommand cmd = cnn.CreateCommand();
cmd.CommandText = "UPDATE database SET shippdate = GetDate() WHERE UPPER(salesman) = UPPER(#salesMan)";
cmd.Parameters.AddWithValue("#salesMan", salesman);
if (cnn.State.Equals(ConnectionState.Closed))
{
cnn.Open();
}
cmd.ExecuteNonQuery();
cnn.Close();
As mentioned in above answers, yes, writing queries in this way is not a good way to do it. But still if you want to do it that way only, you will have to change:
sql.Append("where salesman = "' + salesman + "'");
to
sql.Append("where salesman = '" + salesman + "'");
i have this sql command
string myreg = "select registration_no from truck where truck_id ='" + truckID + "'";
MySqlCommand cmd = new MySqlCommand(myreg, conn);
i want to put the value of myreg to my RegistrationNo.Text label.
i have this RegistrationNo.Text = myreg; and it displays select registration_no from truck where truck_id on my page
You need to read something about the workings of ADO.NET and its providers.
To get the result of that query in your textbox you need
Open a connection to your MySql Server
Prepare a command to send to the Server
Get back the result
Write the result to your textbox
All these passages requires the use of specific classes and some code to glue everything together
// Prepare your command using a parameter placeholder
string myreg = "select registration_no from truck where truck_id =#id";
// Build the connection to the server and build the command to execute
using (MySqlConnection cnn = new MySqlConnection(.... the connection string that identifies your server and db ))
using (MySqlCommand cmd = new MySqlCommand(myreg, cnn))
{
// Open the connection
cnn.Open();
// Add the parameter expected
cmd.Parameters.Add("#id", MySqlDbType.VarChar).Value = truckID;
// Execute the command and get back the return value (if found)
object result = cmd.ExecuteScalar();
// Check if the ExecuteScalar has returned something
if(result != null)
RegistrationNo.Text = result.ToString();
else
... message to your user about the failed search ...
}
PS. I have assumed that your variable truckID is a string because in your original code you have passed it between single quotes, but if it is an integer then you need to modify the parameter type to MySqlDbType.Int32
Also, I have used the ExecuteScalar method instead of ExecuteReader because I think that your query returns just a row with a single column and for this task it is better to use ExecuteScalar
You can use datareader also.See MSDN documentation here.
using (connection)
{
SqlCommand command = new SqlCommand(
"SQL Query",
connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
}
I'm trying to make an ATM Simulator. When I want to add some money in my account which is registered in SQL Server, I don't know how to add a value over the old value.
My SQL Table is like this:
Name | Surname | Pin | Money
When i want to add Money from textBox in the Money column I don't know how.
Code:
con.Open();
string connString = "";
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select * from Useri where Pin='" + textBox1_Pin.Text + "' ";
var reader = cmd.ExecuteReader();
double balanciFillestar = Convert.ToDouble(reader[3]);
double balanciRi = balanciFillestar + double.Parse(textBox_shuma.Text);
cmd.CommandText = "update Useri set Shuma =" + balanciRi + "";
cmd.ExecuteNonQuery();
con.Close();
The most immediate need would be to filter the update statement, so instead of this:
cmd.CommandText = "update Useri set Shuma =" + balanciRi + "";
you really need this:
cmd.CommandText = "UPDATE Useri SET Shuma = #Shuma WHERE Pin = #Pin";
But, before you can do that we really need to refactor it all.
var selectSql = "SELECT Shuma FROM Useri WHERE Pin = #Pin";
var updateSql = "UPDATE Useri SET Shuma = #Shuma WHERE Pin = #Pin";
using (SqlConnection c = new SqlConnection(cString))
{
c.Open();
double balanciFillestar;
using (SqlCommand cmd = new SqlCommand(selectSql, c))
{
cmd.Parameters.AddWithValue("#Pin", textBox1_Pin.Text);
balanciFillestar = Convert.ToDouble(cmd.ExecuteScalar());
}
double balanciRi = balanciFillestar + double.Parse(textBox_shuma.Text);
using (SqlCommand cmd = new SqlCommand(updateSql, c))
{
cmd.Parameters.AddWithValue("#Shuma", balanciRi);
cmd.Parameters.AddWithValue("#Pin", textBox1_Pin.Text);
cmd.ExecuteNonQuery();
}
}
There are a number of things I'm doing here that you'll want to learn from:
The SQL statements are parameterized.
The SqlConnection is not shared.
The ADO.NET objects are wrapped in a using statement.
A SqlDataReader isn't used to get a single value from a single row.
All of these things, with the exception of #4, are equally important.
Point #1 ensures that you're protecting yourself from SQL Injection attacks.
Point #2 is quite simply the only viable way to use the class. It's meant to be constructed, opened, used, and disposed.
Point #3 ensures that the Dispose method is called on all of the objects. This is extremely important with these classes because they implement IDisposable. They do because they handle unmanaged resources (i.e. a connection to a SQL server).
Point #4 is really just an optimization. Data readers are meant for reading very large data sets, one row at a time, to gain performance and resource management. Likewise the data reader is actually left open until it is closed or disposed. Generally speaking there are almost always better API's to use than a data reader unless using it for their express purpose.
Your code is vulnerable against SQL injection. Please consider this and use parameterized query.
string ps= "update Useri set Shuma = Shuma + #shuma WHERE Pin= #pin";
SqlCommand cmd = new SqlCommand(ps, c);
cmd.Parameters.AddWithValue("#shuma", textBox_shuma.Text);
cmd.Parameters.AddWithValue("#pin", textBox1_Pin.Text);
I need to retrieve a value from a field in database. I have the used following code. but the value checkOrderId (which I need) shows the SQL string instead of the value from database. I don't know why it is doing so. Could somebody help me please?
string connectionString = "Data Source = xxyyzz;Initial Catalog = xyz; Integrated Security = True";
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
string tableName = "[GIS].[SecondaryTraffic].[PotentialBackHauls]";
string checkOrderId = "Select TOP 1 OrderID From" + tableName + "ORDER BY InsertDate DESC";
SqlCommand cmd = new SqlCommand(checkOrderId, connection);
//cmd.ExecuteNonQuery();
OpenPop.Pop3.Pop3Client popConn = new OpenPop.Pop3.Pop3Client();
if (orderIdentity == checkOrderId)
{
popConn.DeleteMessage(messageNumber);
}
connection.Close();
I am new and dont have reputation to answer my question immediately. With everybody's help, i got this one solved...Great help, thanx everybody...following is my code.
string connectionString = "Data Source = EAEDEV;Initial Catalog = GIS; Integrated Security = True";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string tableName = "[GIS].[SecondaryTraffic].[PotentialBackHauls]";
string checkOrderId = "Select TOP 1 OrderID From " + tableName + " ORDER BY InsertDate DESC";
SqlCommand cmd = new SqlCommand(checkOrderId, connection);
string valueReturned = (string)cmd.ExecuteScalar();
OpenPop.Pop3.Pop3Client popConn = new OpenPop.Pop3.Pop3Client();
if (orderIdentity == valueReturned)
{
popConn.DeleteMessage(messageNumber);
}
connection.Close();
}
You need to execute the query and check the results, here you are just comparing a string with the query SQL.
Please see here
http://www.csharp-station.com/Tutorial/AdoDotNet/lesson03
for a tutorial.
Your expectation of the result being set into checkOrderId is incorrect. In this instance checkOrderId is just the query to execute and not the actual result.
You need to read the value back from executing the command:
using (var connection = new SqlConnection(connectionString))
using (var comm = new SqlCommand("Select TOP 1 OrderID From [GIS].[SecondaryTraffic].[PotentialBackHauls] ORDER BY InsertDate DESC", connection))
{
connection.Open();
object result = comm.ExecuteScalar(); // This is the key bit you were missing.
if (result != null)
{
// You can cast result to something useful
int orderId = (int)result;
}
} // Both comm and connection will have Dispose called on them here, no need to Close manually.
ExecuteScalar returns the value in the first cell (ie, column 1 row 1) as an object that you can cast to a better type (depending on what type it was in the result-set schema).
If you need to read multiple values, you need to look at ExecuteReader.
There are also other ways of doing this using output parameters, but that would pollute the point of the answer.
You can add space to your query
"Select TOP 1 OrderID From " + tableName + " ORDER BY InsertDate DESC";
Nota : I suggest you to use AddWithValue method with your parameter
string checkOrderId = "Select TOP 1 OrderID From #tableName ORDER BY InsertDate DESC";
SqlCommand cmd = new SqlCommand(checkOrderId, connection);
cmd.Parameters.AddWithValue("#tableName", tableName );
Link : http://msdn.microsoft.com/fr-fr/library/system.data.sqlclient.sqlparametercollection.addwithvalue.aspx
You don't actually run your command anywhere. Instead of the commented-out cmd.ExecuteNonQuery, you should look into the ExecuteScalar method, which allows you to read back a single result value from a query - which is what your query returns.
Add
int i = (Int32) cmd.ExecuteScalar();
right after
SqlCommand cmd = new SqlCommand(checkOrderId, connection);
then the variable i will contain the order id
No, this is not correct. You are comparing the variable orderId to your query string. I doubt that's what you want to do. I imagine you'd be better off calling cmd.ExecuteScalar() to retrieve the actual OrderID value. As noted by other answers, your query string is missing a space. But most importantly, it is bad practice to construct SQL queries in code. Although I can't see a security issue with this code, if you continue to use this method you will probably write code that is vulnerable to SQL injection. I recommend you learn to either use parameters or LINQ to build your queries.