How do I execute an INSERT using SqlCommand? - asp.net

I have another class that creates the connection (see refined class half way down page) and I believe it connects or at lest I do not hit any of the exceptions in run time.
I would now like to insert data into my database but nothing is updated.
I am trying to follow this example but it is for reading.
I did run "querystring" on the show SQL Pane and it does execute correctly. It inserts data properly as a new row.
not sure what to do after my last line? Thanks.
string queryString =
"INSERT INTO UserData UserProfileID, ConfidenceLevel, LoveLevel, HappinessLevel) VALUES ('a051fc1b-4f51-485b-a07d-0f378528974e', 2, 2, 2);";
protected void Button1_Click(object sender, EventArgs e)
{
MySqlConnection database = new MySqlConnection();
database.CreateConn();
Command = new SqlCommand(queryString, database.Connection); //
}

Command.ExecuteNonQuery();
By the way, you're missing a parenthesis in your SQL query string.
And of course, you'd use parameters in a real query (and you will not use string concatenation instead of passing parameters as it'll open doors for destructive SQL injection attacks).

Related

How to insert data in multiple tables at a time?

I have following tables in my MS Access database.
Personal, Partner, ContactDetails, NativeAddress bla bla bal. I created a Wizard in Visual Studio 2012 for above tables. A screenshot is given below. Now I want to submit all data at once in all tables when user presses the submit button. So what syntax should I use now. Please guide.
My code is something like this. Its incomplete and just beginning of my script. So please don't get me wrong.
protected void dataWizard_FinishButtonClick(object sender, WizardNavigationEventArgs e)
{
OleDbConnection con = new OleDbConnection();
con.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\micronets\jobwork-2013\arunthathiyar-sangham\arunthathiyar-web-application\App_Data\arunthathiyar-db.accdb";
string personalDetails = "INSERT INTO PersonalDetails(FirstName, MiddleName, LastName, Sex, Age, DateOfBirth, PlaceOfBirth, EducationalQualification, EmploymentStatus, Profession, PhysicalStatus, BloodGroup) VALUES (#fnPD, #mmPD, #lnPD, #sexPD, #agePD, #dobPD, #pobPD, #eqPD, #esPD, #profPD, #phyicPD, #bgPD)";
string familyDetails = "INSERT INTO FamilyDetails(Relationship, FullName, Status, BloodGroup, EducationalQualification, Profession, EmploymentStatus) VALUES(#relFD, #fnFD, #statusFD, #bgFD, #eqFD, #profFD, #esFD)";
string contactDetails = "INSERT INTO ContactDetails(FlatBuildingStreet, Landmark, Area, City, Pincode, State, Country, Mobile, Telephone, Email) VALUES(#fbsCD, #landCD, #areaCD, #cityCD, #pinCD, #stateCD, #countryCD, #mobCD, #telCD, #emailCD)";
try
{
con.Open();
txtMemAmountReceived.Text = txtPDFirstName.Text;
}
catch
{
txtMemAmountReceived.Text = "Sorry";
}
You're heading in the right direction. Here's what you need to do next:
Create an OleDbCommand object
You have a connection, now you need to create and Command object that can store the SQL text and execute commands against the database. Something like this:
OleDbCommand cmd = new OleDbCommand(personalDetails, con);
Open, execute, close
Then, inside your try block, you want to open the connection, execute the query, and close the connection:
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
Rinse and repeat
You can take it from there as far as executing all three queries. You just need to update the cmd.CommandText property with the text for the other queries you want to execute, and call ExecuteNonQuery again.
you could possibly concatenate all of your query strings into one separated by semicolons(;) So the one large string would be sent to the server and each query would be processed and you would then only have to make one connection to the database.
string myQuery = personalDetails+ "; " + familyDetails + "; " + contactDetails
However i would just make 3 separate connections just so it will be easier to manage all of your parameters. If you ever have to go back and change the query or a parameter it will be a mess.

SqlCacheDependency not working

I would like to add SqlCacheDependency to my app.
So I desided to create littel tesp project and confronted with difficulties.
I use MSSQL 2008. I create new db with table Lines and added several rows.
I executed:
ALTER DATABASE ForTest SET ENABLE_BROKER
in managmeng studio.
Aspx page:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Cache["Lines"] == null)
{
string connectionString =
WebConfigurationManager.ConnectionStrings["ForTest"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
string query = "SELECT dbo.Lines.Id, dbo.Lines.Value FROM dbo.Lines";
SqlCommand cmd = new SqlCommand(query, con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds, "Lines");
SqlCacheDependency empDependency = new SqlCacheDependency(cmd);
Cache.Insert("Lines", ds, empDependency);
}
}
}
protected void btnResult_OnClick(object sender, EventArgs e)
{
var result = Cache["Lines"];
}
}
I run this page and add lines to Cache then I add row in managment studio and when I click on button I expect
that the cache will be changed but cache remains old.
I can't find what I do wrong :( Could you give me some hint how I can solve this problem?
Thanks
Update:
I forger to say that in global.aspx I run:
SqlDependency.Start(
WebConfigurationManager.ConnectionStrings["ForTest"].ConnectionString
);
I had a similar issue. This article: Troubleshooting SqlCacheDependency in SQL Server 2008 and SQL Server 2005 helped me a lot then.
In a few words: the databse was restored from a backup, and the original Windows user that created the database was no longer available. So I changed the database ownership to a valid login, something similar to:
ALTER AUTHORIZATION ON DATABASE::[my_perfect_database_name] TO [sa];
and it works like a charm now.
How did I find the source of the issue? I run the query SELECT * FROM sys.transmission_queue and found the next data in the transmission_status column:
An exception occurred while enqueueing a message in the target queue.
Error: 15517, State: 1. Cannot execute as the database principal
because the principal "dbo" does not exist, this type of principal
cannot be impersonated, or you do not have permission.
This message gave me a key to solving the problem.
There is a mistake in the code;
Definition of sqldependency should be placed before you execute the command,
otherwise it will not subscribe to your sqlcommand, then it won't get notified when your resultset of your command changes.
SqlCacheDependency empDependency = new SqlCacheDependency(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds, "Lines");
I also thought I had an issue with the SqlCacheDependency not being cleared after a change to the table.
Turns out it was because of how I was testing. I was simply editing the rows in the SQL table thru management studio and expecting it to notify and clear the cache. That's not the case! If you are editing the table, you must also re-execute the select sql to kick off the clearing of the cache.

SQL Cache Dependency not working with Stored Procedure

I can't get SqlCacheDependency to work with a simple stored proc (SQL Server 2008):
create proc dbo.spGetPeteTest
as
set ANSI_NULLS ON
set ANSI_PADDING ON
set ANSI_WARNINGS ON
set CONCAT_NULL_YIELDS_NULL ON
set QUOTED_IDENTIFIER ON
set NUMERIC_ROUNDABORT OFF
set ARITHABORT ON
select Id, Artist, Album
from dbo.PeteTest
And here's my ASP.NET code (3.5 framework):
-- global.asax
protected void Application_Start(object sender, EventArgs e)
{
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString;
System.Data.SqlClient.SqlDependency.Start(connectionString);
}
-- Code-Behind
private DataTable GetAlbums()
{
string connectionString =
System.Configuration.ConfigurationManager.ConnectionStrings["UnigoConnection"].ConnectionString;
DataTable dtAlbums = new DataTable();
using (SqlConnection connection =
new SqlConnection(connectionString))
{
// Works using select statement, but NOT SP with same text
//SqlCommand command = new SqlCommand(
// "select Id, Artist, Album from dbo.PeteTest", connection);
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.spGetPeteTest";
System.Web.Caching.SqlCacheDependency new_dependency =
new System.Web.Caching.SqlCacheDependency(command);
SqlDataAdapter DA1 = new SqlDataAdapter();
DA1.SelectCommand = command;
DataSet DS1 = new DataSet();
DA1.Fill(DS1);
dtAlbums = DS1.Tables[0];
Cache.Insert("Albums", dtAlbums, new_dependency);
}
return dtAlbums;
}
Anyone have any luck with getting this to work with SPs?
Thanks!
i figured this out, need to set query options BEFORE creating the SP. got it working when i created the SP as follows:
USE [MyDatabase]
GO
set ANSI_NULLS ON
set ANSI_PADDING ON
set ANSI_WARNINGS ON
set CONCAT_NULL_YIELDS_NULL ON
set QUOTED_IDENTIFIER ON
set NUMERIC_ROUNDABORT OFF
set ARITHABORT ON
go
create proc [dbo].[spGetPeteTest]
as
select Id, Artist, Album
from dbo.PeteTest
GO
You are not returning data from the cache every time. It should be like this:
if (Cache["Albums"]!=null)
{
return (DataTable) Cache["Albums"];
}
else
{
// you need to write coding from database.
}
Another cause can be this in a SQL statement:
AND dbo.[PublishDate] <= GetDate()
The SQLCacheDependency will behave as if the underlying data has changed even if it hasn't, since GetDate() is dynamic (equally if you were to pass DateTime.Now via a #parameter).
This was not obvious to me after re-writing my proc following all the good suggestions above, also not forgetting also to remove "SET NOCOUNT ON" from the proc. SQLCacheDependency expires the cache if the data changes OR the query parameters values change, which makes sense I suppose.
For me using something like this in the stored proc didn't work.
select id, name from dbo.tblTable;
I had to explicitly put in the references like this.
select dbo.tblTable.id, dbo.tblTable.name from dbo.tblTable;
SQL caching won't work if you use select *, also you need to make sure you put dbo (or relevant schema) in front of your table name.
You can also check SQL profiler to verify if your sql is run hope will help you etc....
Note that you cannot use
with (NOLOCK)
in the stored procedure or the the dependency will remain constantly invalid.
This does not appear to be mentioned in the documentation as far as I can tell
I realise that the original poster did not do this but anyone coming here that has the problem stated in the title may have done this so I thought it was worth mentioning.

Asp.Net SQL Refresh page duplicate inserts?

I have a *.aspx page that contains a text box and a button. When the user enters information in to the textbox and clicks post, it inserts the data into my sql database. The issue is, that if the user hits refresh, it will keep inserting the same data into the database. I am pretty sure the whole "click" method is called, not just the insert call. I tried messing with sessions but it complains. I am not really sure what to do. I am looking for a simple easy fix.
protected void PostButton_Click(object sender, EventArgs e)
{
string wpost = (string)Session["WallPost"];
DateTime wtime = (DateTime)Session["WallDateTime"];
if (txtWallPost.Text.Length > 0 && !wpost.Equals(txtWallPost.Text))
{
string strCon = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["SocialSiteConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(strCon))
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO [WallTable] ([UserId], [FriendId], [WallPost]) VALUES (#UserId, #FriendId, #WallPost)";
cmd.Parameters.AddWithValue("#UserId", User.Identity.Name);
cmd.Parameters.AddWithValue("#FriendId", User.Identity.Name);
cmd.Parameters.AddWithValue("#WallPost", txtWallPost.Text);
conn.Open();
cmd.ExecuteNonQuery();
Session.Add("WallPost", txtWallPost.Text);
Session.Add("WallDateTime", new DateTime());
conn.Close();
txtWallPost.Text = "";
LoadWallPosts();
}
}
}
return;
}
If the PostButton_Click is the server handler for the click event on your button then insert code shold be executed only if the user hits the post button - it should not happen in case of refresh.
I am pretty sure is not enough - to be sure put a breakpoint in your PostButton_Click method, hit F5 to run in debug mode and see if the breakpoint gets hit with a refresh.
If so it means that:
you are calling explicitly
PostButton_Click from somewhere
else (Page_Load?)
PostButton_Click was accidentally
set as event handler for some other
event on the page
A quick way of verifying hypotesis 1 & 2 is to run a search for PostButton_Click and see where you are calling it from or if it set as handler for some other element (maybe your form?) in the markup.
Add Response.Redirect(Request.Url.ToString(), false); to your button event and that should solve the problem.
if he refreshes or press the back button the post will happen again, thus your page will process the same data thus insert once again.
You have to change your logic
It would be preferable to redirect the client to another page after the insert, however, if you really need the client stay in the same page, you can use a (bool) variable on your page to state if the insert has been done, and skip the insert logic if it has been executed before

asp.net gridview sort without data rebind

I am trying to make a gridview sortable which uses a stored procedure as a datasource, I would not want it to rerun the query each time to achieve this. How would I get it to work my current code is:
protected override void OnPreRender(EventArgs e)
{
if (!IsPostBack)
{
SqlCommand cmd2 = new SqlCommand("SR_Student_Course_List", new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["RDCV2ConnectionString"].ConnectionString));
try
{
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.CommandTimeout = 120;
cmd2.Parameters.Add("student_id", SqlDbType.Char, 11).Value = student;
cmd2.Connection.Open();
grdCourses.DataSource = cmd2.ExecuteReader();
grdCourses.DataSourceID = string.Empty;
grdCourses.DataBind();
} finally
{
cmd2.Connection.Close();
cmd2.Connection.Dispose();
cmd2.Dispose();
}}}
This code just binds the data when it isn't a postback, the gridview has viewstate enabled. On pressing the column headers a postback happens but no sorting occurs. If anyone has a simple fix for this please let me know or even better an ajax sort which would avoid the postback would be even better. The dataset is relatively small however takes a long time to query which is why I would not like to requery on each sort.
If you are not paging the results, and just doing a read, then something like the jquery tablesorter plugin would be a quick and easy fix. I have used this on tables of up to 1400 rows and works great, although ~> few hundred probably better on slow putas.
If the gridview is editable, then aspnet event/input validation might spit a dummy if you don't go through the proper registration of client scripts etc.
You could try storing the data in view state (or cache).
In your case, I would use a SqlDataAdapter and fill a DataTable. Then, put the DataTable into a Session variable. When the GridView is sorting, check if the Session variable still exists. If it does not, then fill the DataTable again. Finally sort the DataTable using a DataView and rebind the GridView with the DataView.

Resources