DynamicSQL with ASP.NET Parameters not being set - asp.net

I use this dynamicSQL piece of code.
Problem is, the #ID_USER and #SEARCH stays raw in the SQL query when I check the cmd.CommandText value at runtime, it reads
"SELECT Comment FROM Comments WHERE UserId = #ID_USER AND Comment like '% #SEARCH %'"
so the syntax is correct and the cmd.Parameters ResultView .SqlValuein VS2012 gives me the correct input values for #USER_ID and #SEARCH
Thanks.
{
List<string> searchResults = new List<string>();
//Get current user from default membership provider
MembershipUser user = Membership.Provider.GetUser(HttpContext.User.Identity.Name, true);
if (user != null)
{
if (!string.IsNullOrEmpty(searchData))
{
// SqlCommand cmd = new SqlCommand("Select Comment from Comments where UserId = '" + user.ProviderUserKey + "' and Comment like '%" + searchData + "%'", _dbConnection);
/**********************************************/
_dbConnection.Open();
const string QUERY =
#"SELECT Comment" +
#" FROM Comments" +
#" WHERE UserId = #ID_USER" +
#" AND Comment like '% #SEARCH %'";
var cmd = new SqlCommand(QUERY, _dbConnection);
cmd.Parameters.AddWithValue("#ID_USER", user.ProviderUserKey.ToString());
cmd.Parameters.AddWithValue("#SEARCH", searchData.ToString());
/**********************************************/
SqlDataReader rd = cmd.ExecuteReader();
while (rd.Read())
{
searchResults.Add(rd.GetString(0));
}
rd.Close();
_dbConnection.Close();
}
}
return View(searchResults);
}

No, it is correct that the parameters remain in the command text.
This is because what is actually passed to the server is something like the below:
exec sp_executesql N'SELECT Comment FROM Comments WHERE UserId = #ID_USER AND Comment like ''% + #SEARCH %''',
N'#ID_USER int,#SEARCH nvarchar(max)',
#ID_USER=1,
#SEARCH=N'some search text';
So your parameters remain in place even when it is passed to the server. This is why you can still see them in your command text.
As an aside your query will not work as expected, in this line:
AND Comment like '% #SEARCH %'
You are looking for where Comment actually contains "#Search" rather than the value assigned to the parameter. What you need is:
AND Comment like '%' + #SEARCH + '%'
Another, slightly unrelated point is that there is no need to, nor is it useful to reuse SqlConnections. Define a new one for each connection. .NET is smart enough to reuse connections by pooling them, don't reinvent the wheel. Also use using blocks to ensure your disposable class are disposed of:
So I would make your whole reader block as follows:
string sql = "SELECT Comment FROM Comments WHERE UserID = #ID_USER AND Comment LIKE '%' + #Search + '%'";
using (var connection = new SqlConnection(YourConnectionString))
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue("#ID_USER", user.ProviderUserKey.ToString());
command.Parameters.AddWithValue("#SEARCH", searchData.ToString());
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
searchResults.Add(rd.GetString(0));
}
}
}

Related

Can't Update Database from ASP.NET Webform

I can't get an ASP.NET webform to update a database. I'm trying to edit an existing record in the database. The webform populates the data from the record into the form. The user then changes data and updates the record in the database when the form is submitted.
The problem is that nothing is changed in the database when a modified form is submitted. What am I doing wrong here? The SQL works in MSSQL Management Studio.
Thanks.
private void SaveToDatabase ()
{
using (SqlConnection conn = new SqlConnection (_connectionString_Bluebook))
{
conn.Open ();
string sql = #"update Companies
set CompanyName=#CompanyName, AccountNo=#AccountNo
where AccountNo=" + _accountNo;
using (SqlCommand command = new SqlCommand (sql, conn))
{
command.Parameters.Add (new SqlParameter ("#CompanyName", TextBox_CompanyName.Text));
command.Parameters.Add (new SqlParameter ("#AccountNo", TextBox_Account.Text));
command.ExecuteNonQuery ();
}
conn.Close ();
}
}
Try adding a parameter for the original account number to your query. The example below uses strongly-typed parameters for security and performance, taking a guess at your actual SQL data types and column lengths, which you should change to your actual definitions.
private void SaveToDatabase()
{
using (SqlConnection conn = new SqlConnection(_connectionString_Bluebook))
{
conn.Open();
string sql = #"update dbo.Companies
set CompanyName=#CompanyName, AccountNo=#AccountNo
where AccountNo=#OriginalAccountNo;
IF ##ROWCOUNT = 0 RAISERROR('Account number %s not found',16,1,#OriginalAccountNo)";
using (SqlCommand command = new SqlCommand(sql, conn))
{
command.Parameters.Add(new SqlParameter("#CompanyName",SqlDbType.VarChar,100).Value = TextBox_CompanyName.Text;
command.Parameters.Add(new SqlParameter("#AccountNo", SqlDbType.Char, 10).Value = TextBox_Account.Text;
command.Parameters.Add(new SqlParameter("#OriginalAccountNo", SqlDbType.Char, 10).Value = _accountNo;
command.ExecuteNonQuery();
}
}
}
If the row is still not updated as expected, make sure _accountNo contains the proper value.
EDIT:
I added a RAISERROR statement to the SQL batch to facilitate this, which you could leave in the code if the not found condition should never occur.
If the SQL Params are not working, then try this way:
comm = new SqlCommand("update student_detail set s_name= '" + txtname.Text + "', age= "+txtage.Text+" , course=' " + txtcourse.Text + "' where roll_no = " + txtrn.Text + " ", conn);
Try to place the debugger and provide the exact error of the compiler

Response.write only shows the first record from the database (this.session.sessionid)

I've got a problem for the past few days. I will explain short what i've did.
I have a table created in the database called 'Cart'. This Cart cointains: ClientID, Artical number, and quantity. In the ClientID, a session.sessionID stored. In the Artical just a number like 1012. And in quantity a number like 1 or 3.
What I would like to, is retrieve all the records, with the session.session id of the user.
It does work in the page, but only the first record of the like 4-5 records that are in the cart table is shown. I think i comes due the problem that it looks for this.session.sessionidand when it found one, it doesn't look any further then that.
I've tried to loop through the query where sessions is. But it won't let me loop because it doesn't know for? Even if I loop the whole query outside of it like this:for (int i = 0; i < sessies.Length; i++) It will show more records.. but they are all the first records.. I know that was a stupid try but I can always try..
Looked for all over the internet but couldn't find the solution to this.
Hope to get a response soon from somebody. It would be gratefull.
Used the following code:
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["GarageConnectionString"].ToString()))
{
string sessions = this.Session.SessionID;
SqlCommand cmd = new SqlCommand("SELECT * FROM cart where ClientID='" + sessions + "'", cn);
cn.Open();
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
rdr.Read();
TextBox1.Text = rdr[2].ToString();
Response.Write("<br>" + ("Sessie id "+rdr[1].ToString()));
Response.Write("<br>" + ("Artikel nummer "+rdr[2].ToString()));
Response.Write("<br>" + ("Aantal "+rdr[3].ToString()));
cn.Close();
}
SqlDataReader advances to the next record in the set: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.read%28v=vs.110%29.aspx
Call Read() in a loop, like so:
using (SqlConnection cn = newSqlConnection(ConfigurationManager.ConnectionStrings["GarageConnectionString"].ToString()))
{
string sessions = this.Session.SessionID;
SqlCommand cmd = new SqlCommand("SELECT * FROM cart where ClientID='" + sessions + "'", cn);
cn.Open();
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (rdr.Read())
{
TextBox1.Text = rdr[2].ToString();
Response.Write("<br>" + ("Sessie id "+rdr[1].ToString()));
Response.Write("<br>" + ("Artikel nummer "+rdr[2].ToString()));
Response.Write("<br>" + ("Aantal "+rdr[3].ToString()));
}
cn.Close();
}
You should loop through the datareader: ie:
while (rdr .Read())
{
Console.WriteLine("{0}\t{1}", rdr .GetInt32(0),
rdr .GetString(1));
}
Each call to SqlDataReader.Read() gets a single row, unless there are no more rows when it returns false.
So you need to loop to get all rows:
while (rdr.Read()) {
// Use rdr methods to access the values from the current row.
}
Use While Loop- Example
if (rdr .HasRows)
{
while (rdr .Read())
{
Console.WriteLine("{0}\t{1}", rdr .GetInt32(0),
rdr .GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
rdr .Close();

why is my insert not inserting a record in database

I am trying to insert a record into the database using the below method. I am calling this method in a button click event but for some reasons no record is being inserted.
There are four fields which need to be inserted: rpttemplateid - I am getting that field from another database table and all the other feilds are just static values.
What am i doing wrong below?
public void updatereporttemplate()
{
string cnn = WebConfigurationManager.ConnectionStrings["Underwriting"].ConnectionString;
SqlConnection cnn1 = new SqlConnection(cnn);
cnn1.Open();
string getrptdesc = "select max(rptdesc) + 1 from report_description where rptdesc < 999 and rptdesc is not null";
SqlCommand cmd = new SqlCommand(getrptdesc, cnn1);
SqlDataReader sdr = cmd.ExecuteReader();
sdr.Read();
int getcount = int.Parse(sdr[0].ToString());
sdr.Close();
string commandtext1 = "INSERT INTO report_template" + "(rpttemplateid,rpttemplatedescr,minsubs,minmebers) " +
" Values( " + getcount + "," + " " + " , " + 0 + "," + 0 + ")";
SqlCommand command1 = new SqlCommand
{
CommandText = commandtext1,
Connection = cnn1
};
You are missing command1.ExecuteNonQuery();
Also, have you considered using an IDENTITY column in your table instead of trying to manually set the count? What if that page is hit by multiple people at the same time?
You need to open the connection
cnn1.Open();
And then execute the command
command1.ExecuteNonQuery();

asp.net Login Website from database

I have a website with a login, from a database.
This is my code :
protected void SignIn_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=MICROSOF-58B8A5\\SQL_SERVER_R2;Initial Catalog=Movie;Integrated Security=True");
con.Open();
string cmdStr = "select count(*) from Users";
cmdStr += "where Username='" + UsernameSignIn.Text + "'";
cmdStr+= "AND Password='"+PasswordSignIn.Text+"'";
SqlCommand cmd = new SqlCommand(cmdStr, con);
int i = Convert.ToInt16(cmd.ExecuteScalar());
if (i == 0)
{
ErrorSignIn.Text = "Sorry, Wrong Username or Password";
}
else
{
Response.Redirect("HomeAfter.aspx");
}
}
for some reason, I run into an error :
Incorrect syntax near '-'
.
(for this line : int i = Convert.ToInt16(cmd.ExecuteScalar()); )
Thanks,
There is no spacing. Your query looks like this:
select count(*) from Userswhere Username='...'AND Password='...'
Add spaces, like so:
string cmdStr = "select count(*) from Users";
cmdStr += " where Username='" + UsernameSignIn.Text + "'";
cmdStr+= " AND Password='"+PasswordSignIn.Text+"'";
Aside from the fact that this is particularly crude as a form of authentication (you really ought to consider using the built-in ASP.NET Membership provider(s)) you should at a minimum be using parameterized SQL queries, rather than concatenating plain text to create your SQL statement. Also, I notice that your "login" arrangement simply does a response.redirect to the HomeAfter.aspx page without storing anything to be re-used that will indicate the user has already successfully logged in, such as a cookie or a sesssion variable.
Is there any particular reason for all this, or is it because you're just starting out and you need to study up a bit?

Update database in asp.net not working

i have in asp.net a few textboxes and i wish to update my database with the values that they encapsulate .
The problem is that it doesn't work and although it doesn't work, the syntax seems correct and there are no errors present . Here is my linkbutton :
<asp:linkbutton id="clickOnSave" runat="server"
onclick="Save_Click" Text="Save Profile" />
and my update function
protected void Save_Click(object sender, EventArgs e)
{
SqlConnection con = new System.Data.SqlClient.SqlConnection();
con.ConnectionString = "DataSource=.\\SQLEXPRESS;AttachDbFilename=C:\\Users\\alex\\Documents\\seeubook_db.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
con.Open();
String commandString = "UPDATE users SET last_name='" + Text4.Text.Trim() + "' , first_name='" + Textbox1.Text.Trim() + "' , about_me='" + Textbox5.Text.Trim() + "' , where_i_live='" + Textbox2.Text.Trim() + "' , where_i_was_born='" + Textbox3.Text.Trim() + "' , work_place='" + Textbox4.Text.Trim() + "' WHERE email='" + Session["user"] + "'";
SqlCommand sqlCmd = new SqlCommand(commandString, con);
sqlCmd.ExecuteNonQuery();
con.Close();
}
I'm always a bit weary about the User Instance=true in a connection string..... at times, it tends to create a new MDF file "on the fly" and when you update that MDF, then your changes might be just "gone" one your app has completed running.... See MSDN docs on User Instances.
I would suggest that you:
attach your MDF file to SQL Server Express on your machine, using SQL Server Express Management Studio
then use a server-based approach to your SQL Server Express database rather than attaching a file...
In that case, your database connection string would then look something like:
server=.\\SQLEXPRESS;database=YourDatabaseName;Integrated Security=SSPI;
And while you're at it, I would also recommend to:
wrap your SqlConnection and SqlCommand into using blocks to ensure proper disposal
open your connection as late as possible
use a parametrized query instead of concatenating together your SQL command - doing so is a wide open door for SQL injection attacks!
So your code would look something like this:
string connStr = "server=.\\SQLEXPRESS;database=YourDatabaseName;Integrated Security=SSPI;";
string cmdStmt = "UPDATE dbo.Users SET last_name = #lastName, " +
"first_name = #firstName, about_me = #aboutMe, where_i_live = #whereILive, " +
"where_i_was_born = #whereIWasBorn, work_place = #workPlace " +
"WHERE email = #userEMail";
using(SqlConnection sqlCon = new SqlConnection(connStr))
using(SqlCommand sqlCmd = new SqlCommand(cmdStmt, sqlCon))
{
// define parameters
sqlCmd.Parameters.Add("#lastName", SqlDbType.VarChar, 50);
sqlCmd.Parameters["#lastName"].Value = Text4.Text.Trim();
// and so on for all the parameters
sqlCon.Open();
sqlCmd.ExecuteNonQuery();
sqlCon.Close();
}
Debug! Look your LinkButton Click Event really go into Save_Click function. And then check 'sqlCmd.ExecuteNonQuery();' return result.
You need to write your code for filling Textbox's at page load as below :
public page_load()
{
if(!ispostBack)
{
// Write code to fill controls first time
}
}

Resources