This is my first time creating a web api from scratch and I'm trying to get a selected value in a drop down bow to trigger an sql search and make the appropriate item appear in a text box. below is the relevant code
protected void btnRetrieve_Click(object sender, EventArgs e)
{
try
{
string pNameTemp = DropDownList1.SelectedValue;
myConnection.Open();
string query = ("SELECT sName from [dbo].[Table] WHERE (pName LIKE " + pNameTemp + ")");
SqlCommand sqlCmd = new SqlCommand(query, myConnection);
txtSkill.Text = sqlCmd.ExecuteScalar().ToString();
myConnection.Close();
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
it seems to search the correct name but when it comes to updating the txtSkill, I get the exception 'invalid column name' pop up, are there any obvious reasons as to why this is happening that i'm missing? any advice would be appreciated
In fact, you are missing '' for the parameter of the query.
Try to use this query.
SqlCommand sqlCmd = new SqlCommand(#"SELECT sName from [dbo].[Table] WHERE pName LIKE '{pNameTemp}'", myConnection);
But I recommend you to use SqlParameter in C# to avoid SQL Injection
SqlCommand com = new SqlCommand("SELECT sName from [dbo].[Table] WHERE pName LIKE #field", myConnection);
myConnection.Parameters.AddWithValue("#field", pNameTemp);
But normally, when we use LIKE, we should put in % because it gives all results contains keyword. LIKE without % doesn't make sense. So :
SqlCommand com = new SqlCommand("SELECT sName from [dbo].[Table] WHERE pName LIKE #field", myConnection);
command.Parameters.AddWithValue("#field", "'%" + pNameTemp + "%'");
There are some options in the LIKE clause:
%: The percent sign represents zero, one, or multiple characters
_ The underscore represents a single character
Related
I am having an issue with the increment for the ID. The ID would increase by one every time I click insert, but the problem occurs when the ID 2, it would insert the values twice, if ID 3, it would insert the values three times, and so on.
There are couple of options that I have been trying. One is Max and the other one is finding the last inserted value and add one to the ID just.
I would appreciate if anyone can help me out with this. Thanks
public partial class LoginInfo : System.Web.UI.Page
{
static string myConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
private void GenerateID()
{
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myQuery1 = "Select Count(S_ID) from Student_Name";
SqlCommand cmd = new SqlCommand(myQuery1, myConnection);
myConnection.Open();
int addOneS_ID_Table1 = Convert.ToInt32(cmd.ExecuteScalar());
myConnection.Close();
addOneS_ID_Table1++;
lblstdID.Text = addOneS_ID_Table1.ToString();
myConnection.Open();
cmd.CommandText = "Select Count(P_ID) from Student_Pass";
int addOneP_ID_Table2 = Convert.ToInt32(cmd.ExecuteScalar());
myConnection.Close();
addOneP_ID_Table2++;
lblstdPass.Text = addOneP_ID_Table2.ToString();
/*-----------------------------------------------------------------*/
//SqlConnection myConnection = new SqlConnection(myConnectionString);
//SqlCommand cmd = new SqlCommand("SELECT MAX(S_ID) as max_S_ID from Student_Name",myConnection);
//cmd.CommandType = CommandType.Text;
//myConnection.Open();
//lblstdID.Text = Convert.ToString(cmd.ExecuteScalar());
//cmd.CommandText = "SELECT MAX(P_ID) as max_P_ID FROM Student_Pass";
//lblstdPass.Text = Convert.ToString(cmd.ExecuteScalar());
//myConnection.Close();
}
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
GenerateID();
}
}
protected void btnInsert_Click(object sender, EventArgs e)
{
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myQuery = "Insert into Student_Name(S_ID,STUDENT_NAME) VALUES" + "(#S_ID,#STUDENT_NAME)";
SqlCommand cmd = new SqlCommand(myQuery,myConnection);
cmd.Parameters.Add("#S_ID", SqlDbType.Int).Value = lblstdID.Text;
cmd.Parameters.Add("#STUDENT_NAME", SqlDbType.VarChar).Value = txtstdName.Text;
if(myConnection.State == ConnectionState.Closed)
{
myConnection.Open();
}
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
//Second Table
cmd.CommandText = "Insert into Student_Pass(P_ID,PASSWORD) VALUES" + "(#P_ID,#PASSWORD)";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#P_ID", SqlDbType.Int).Value = lblstdPass.Text;
cmd.Parameters.Add("#PASSWORD", SqlDbType.VarChar).Value = txtStdPass.Text;
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
myConnection.Close();
GenerateID();
lblResult.Text = "Successfully Saved";
GridView1.DataBind();
}
}
Problem is with your query since you are getting COUNT(S_ID) which is going to get you count of records doesn't necessarily will give exact ID number. You should rather try MAX(S_ID) or ORDER BY clause saying
Select MAX(S_ID) from Student_Name
(OR)
Select TOP 1 S_ID from Student_Name ORDER BY S_ID DESC;
But recommended, You should actually go with SQL Server ##IDENTITY or SCOPE_IDENTITY() to get the last inserted record ID (assuming that S_ID is an IDENTITY column)
It's highly recommended to not use max or top in order to determine the "next" identifier to use, simply because of the cost associated with it.
However, there are some other pitfalls to using max and top especially if there is a chance that nolock is used (which is a whole other conversation). I've seen a lot of web applications use max and has proven to be a performance killer.
Rahul is right, ##identity or scope_identity are good alternatives. However, I think this calls for using a native SQL Server sequence, which was introduced in SQL Server 2012. It was something that application developers have been waiting for and Microsoft finally delivered.
The issue with using ##identity or scope_identity is that you actually have to write rows to some table before you can even contemplate doing something.
This makes it a bit more costly and messier than what it may need to be. In the case of using a sequence, you can issue a new sequence number and then decide what to do and once you decide what to do you're still guaranteed that you're the only one with that sequence number.
You would create a sequence like this. You should check out the documentation as well.
create sequence dbo.StudentIdSeq
as int -- this can be any integer type
start with 1 -- you can start with any valid number in the int, even negative
increment by 1;
go
Then you issue new sequence numbers by doing this ...
select next value for StudentIdSeq;
It may still be good to create a stored procedure with an output parameter that you can call from C# (which is what I would do). In fact you may want to take it a step further, in the case that you have a bunch of sequences, and create a slick stored procedure that will get a new sequence based on the type that is being requested from the caller.
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 + "'");
This had to be a simple, ordinary SQL insert method but when I run it and I click "button1" I get the error
An unhandled exception of type 'system.data.sqlclient.sqlexception' occurred in system.data.dll
Does anyone know what the problem is?
namespace InsertDeleteUpdate_Login
{
public partial class Form1 : Form
{
SqlConnection cn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\C #\InsertDeleteUpdate-Login\InsertDeleteUpdate-Login\Database1.mdf;Integrated Security=True");
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;
public Form1()
{
InitializeComponent();
cmd.Connection = cn;
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text != "" && textBox2.Text != "")
{
cn.Open();
cmd.CommandText = "INSERT INTO info (ID,Name,Password)" + " VALUES ('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "')'";
cmd.ExecuteNonQuery();
cmd.Clone();
MessageBox.Show("Inserare reusita");
cn.Close();
}
}
}
}
The root cause of your problem is that you are not using parameterized queries and are trying to create an sql string on the fly. As a result you make an error in the assembling code of that string. But if you use a parameterized query the chance of running into an issue like that is a lot lower because you don't have to mess about with quotes and the like. On top of this, you cannot have a sql injection attack if you use parameters and it makes the code more readable too.
Read http://www.dotnetperls.com/sqlparameter on how to use a parameterized query the way it should be done and don't just fix the textual error in the querystring. It is not the way it is supposed to be done.
This is a good explanation too : http://www.dreamincode.net/forums/topic/268104-parameterizing-your-sql-queries-the-right-way-to-query-a-database/
I can't add comments yet, but it looks like you might have an extra single quote after the last close bracket that shouldn't be there.
As mentioned by several people above, you should ALWAYS parameterise your queries, and you also have a trailing single quote, which is most likely what SQL Server is choking on.
Try something like this:
cmd.CommandText = "INSERT INTO info (ID, Name, Password) VALUES (#ID, #Name, #Password)";
cmd.Parameters.AddWithValue("#ID", textBox1.Text);
cmd.Parameters.AddWithValue("#Name", textBox2.Text);
cmd.Parameters.AddWithValue("#Password", textBox3.Text);
cmd.ExecuteNonQuery();
private void btnSubmit_Click(object sender, EventArgs e)
{
OleDbCommand cmd;
string cmdstring = "INSERT INTO Names (Surname,FName) VALUES('" + txtSurname.Text + "','" + txtFName.Text + "')";
OleDbConnection myConnection = new OleDbConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
cmd = new OleDbCommand(cmdstring, myConnection);
myConnection.Open();
cmd.ExecuteNonQuery();
myConnection.Close();
}
I want to add Surname and FName to access database, but an error has been shown like this "syntax error".
I don't know why.
Here are 2 possible reasons your query fails.
Names is a reserved word.
Surname or FName values which include an apostrophe.
You can avoid the first problem by enclosing the table name in square brackets ... [Names]. But if possible it would be better to choose a different name.
If you switch to a parameter query as others suggested, you can avoid the second problem. But in that case, still bracket the table name.
I have a sql select statement in my VS2005 C# server-side coding for a web application and I am meeting some errors.
Below is a screenshot of the controls in the webpage:
Data Source SqlDataSource1 : Query:SELECT [Name] FROM [Users].
Dropdownlist UserNameList : Lists all userName retrieved from SqlDataSource1.
Checkboxes AdminCb and UserCb : Automatically checks if the userType of the userName is as.
Button loadUser : Gets the user type and checks the check boxes accordingly.
Below is my code for my loadUser button
SqlConnection conn = new SqlConnection("Data Source=DATASOURCE");
string sql = string.Format("SELECT [User Type] FROM [Users] where Name like " + UserNameList.Text);
SqlCommand cmd = new SqlCommand(sql, conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
if(sql== "Administrator"){
AdminCb.Checked=true;
}
if(sql== "User"){
UserCb.Checked=true;
}
Currently I am stuck with the error (Wong is the 2nd word of the user's name):
Questions:
1) How can change my Sql query so that it can take in more than 1word?
2) And will I be able to check boxes once I am able to run my sql query?
Thank You.
You must have to use Parameter and call the ExecuteScalar() method instead of ExecuteNonQuery().
string sql = "SELECT [User Type] FROM [Users] where [Name]=#Name";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#Name",SqlDbType.VarChar,50).Value=UserNameList.Text;
conn.Open();
Object result=cmd.ExecuteScalar();
conn.Close();
if(result!=null)
{
string usertype=result.ToString();
if(usertype=="Administrator")
{}
else
{}
}
In case, if result returned from the database contains more then one rows then use ExecuteReader() method.
string sql = "SELECT [User Type] FROM [Users] where [Name] like #Name";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#Name",SqlDbType.VarChar,50).Value="%" + UserNameList.Text + "%";
conn.Open();
SqlDataReader result=cmd.ExecuteReader();
while(result.Read())
{
///
}
result.Close();
conn.Close();
Since you are concatenating the SQL string, if the input itself has a single quote in it, it thinks this is the end of the input, and the continuing input is SQL statements, which is why you may be getting that error.
Switch to using a parameter, or make sure any single quotes are escaped as a pair of single quotes, like:
string sql = string.Format("SELECT [User Type] FROM [Users] where Name like " + UserNameList.Text.Replace("'", "''"));
Since the error is indicating there is something wrong with the Name, I would take a closer look at this line:
string sql = string.Format("SELECT [User Type] FROM [Users] where Name like " + UserNameList.Text);
If you are using string.Format, you might as well use it
string sql = string.Format("SELECT [User Type] FROM [USERS] where Name like {0}", UserNameList.Text);