We have a stored proc that grabs that data from a table, let's call it table1 from one db1 and populates a table, called table2 in db2.
We scheduled this stored proc to perform this function like every 5 minutes. This works fine.
Given that users mostly leave their apps while performing other administrative functions, we have created a refresh button that refreshes the GridView upon clicking the button.
Protected Sub Refresh_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Refresh.Click
' Clean up text to return the GridView to it's default state
strSearch.Text = ""
SearchString = ""
gridView1.DataBind()
End Sub
We would like to both click this refresh button to both to have the stored procedure update table2 and at same time, refresh the GridView.
I know that gridview1.Databind() refreshes the GridView with latest data from table2 but how do I ensure that table2 is first updated with data from table1 using the stored proc before refreshing the GridView.
Kenny I have prepared complete code in vb for you, take a look:
Private Sub CallRefresh()
Dim connectionString As String = "Initial Catalog=myDataBase;data source=myServer;Integrated Security=SSPI;"
Dim storedProcName As String = "ActivateServerTask"
Dim conn As SqlConnection = New SqlConnection(connectionString)
conn.Open()
Dim command As SqlCommand = New SqlCommand(storedProcName, conn)
command.CommandType = CommandType.StoredProcedure
command.Parameters.Add(New SqlParameter("#taskId", 1))
command.ExecuteNonQuery()
command.Dispose()
conn.Close()
conn.Dispose()
End Sub
Protected Sub Refresh_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Refresh.Click
CallRefresh()
gridView1.DataBind()
End Sub
CallRefresh opens connection, executes "ActivateServerTask" stored procedure with "taskId" parameter and finally closes connection...
Take notice I am using connection to sql with integrated security.
You can find other connection strings here:
http://www.connectionstrings.com/
Happy coding Kenny!
Just call your stored procedure from application before you call gridView1.DataBind()
This is how you call a stored procedure from your code:
public object ExecuteStoredProcedureAsValue(SqlConnection conn,
string storedProcName,
List<SqlParameter> parameters)
{
using (var command = new SqlCommand(storedProcName, conn)) {
command.CommandType = CommandType.StoredProcedure;
if (parameters != null)
parameters.ForEach(p => command.Add(param));
object result = null;
using (var reader = command.ExecuteReader()) {
while (reader.Read())
{
result = reader[0];
break;
}
}
return result;
}
}
Take notice that "conn" is SqlConnection object. You should initialize and open sql connection before calling this code.
Related
My new application page is getting a timeout error every hour or so after getting some traffic on the page, and by traffic I mean users submitting 5-10 applications. How do I find the cause of the connections getting tied up?
This has been an issue in the past so whenever I use a sql data reader object I make sure to implement the "Using" statement. I've also made sure that the thread isn't aborted before the data reader is disposed of. I doubt that my use of data readers is the issue, so maybe it's my non-query code that's causing the issue, but I can't see why.
I also use a few sqldatasource objects for my dropdownlist controls, and as far as I know it wouldn't be the source of my issue.
See code example for how I use my sql objects.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Using drApp As SqlDataReader = LookupAppByID()
'some code
drApp.Close()
End Using
End Sub
Public Function LookupAppByID() As SqlDataReader
Dim Command As New SqlClient.SqlCommand
Command.Connection = GetDBConnection()
Command.CommandType = CommandType.Text
Command.CommandText = "select statement"
Return Command.ExecuteReader(CommandBehavior.CloseConnection)
End Function
Public Function UpdateAppStatus() As Integer
UpdateAppStatus = 0
Using Command As New SqlClient.SqlCommand("update statement", GetDBConnection())
UpdateAppStatus = Command.ExecuteNonQuery()
Command.Connection.Close()
Command.Connection.Dispose()
Command.Dispose()
End Using
End Function
Public Function GetDBConnection() As SqlClient.SqlConnection
Dim connection As New SqlClient.SqlConnection
connection.ConnectionString = "connection string"
connection.Open()
Return connection
End Function
Obviously I expect it to chug along without a hitch but when users start hitting the page it gets this error: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Is there a problem with my code?
How can I narrow down what is causing this issue?
I would keep the database objects local so I can ensure that they are closed and disposed. Create and dispose within one method. I created a class so you can easily pass all its properties in a single variable.
'User Interface Code
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim id As Integer 'No sure where the value comes from
Using dtApp As DataTable = DataAccess.LookupAppByID(id)
'some code
End Using
End Sub
Protected Sub Update_Click(sender As Object, e As EventArgs) Handles Update.Click
Dim Applic As New ApplicationData()
Applic.ApplicantsName = txtName.Text
Applic.ID = CInt(txtID.Tex)
Applic.ApplicationStatus = "Approved"
Dim retVal = DataAccess.UpdateAppStatus(Applic)
If retVal = 1 Then
'Alert user of success
Else
'Alert user of failure
End If
End Sub
Public Class ApplicationData
Public Property ID As Integer
Public Property AppDate As Date
Public Property ApplicantsName As String
Public Property ApplicationStatus As String
End Class
Public Class DataAccess
Private Shared ConString As String = "Your connection string"
Public Shared Function LookupAppByID(AppID As Integer) As DataTable
Dim dt As New DataTable
Using cn As New SqlConnection(ConString)
Using Command As New SqlCommand("select * From YourTable Where ID = #ID", cn)
Command.Parameters.Add("#ID", SqlDbType.Int).Value = AppID
cn.Open()
dt.Load(Command.ExecuteReader)
End Using
End Using
Return dt
End Function
Public Shared Function UpdateAppStatus(App As ApplicationData) As Integer
Dim AppStatus = 0
Using cn As New SqlConnection(ConString)
Using Command As New SqlClient.SqlCommand("Update YourTable Set Status = #Status Where ID = #ID;", cn)
Command.Parameters.Add("#Status", SqlDbType.VarChar, 50).Value = App.ApplicationStatus
Command.Parameters.Add("#ID", SqlDbType.Int).Value = App.ID
cn.Open()
AppStatus = Command.ExecuteNonQuery()
End Using
End Using
Return AppStatus
End Function
End Class
I am having a library system database. I want to include a search box where I can search for a book name. I am using sql server. I know how to write a sql statement using the LIKE %''% clause, but the thing is I am writing this sql statement in a separate file and include that in the sub method in vb.net. How can I make that statement use the text entered in textbox?
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim str As String = ("Data Source=.\INSTANCE;initial catalog=example;user=sa;password=gariahat")
Dim con As New SqlConnection(str)
Dim cmd As New SqlCommand("select * from item where book_id like '%" + Trim(TextBox1.Text) + "%'", con)
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet()
If (da.Fill(ds, "item")) Then
ItemDataGridView.DataSource = ds.Tables(0)
MessageBox.Show("match found")
Else
MessageBox.Show("match not found")
End If
End Sub
I know this sub will work if I include the sql statement in the sub itself. But I use squaler to store my sql stored procedures and use those file in my sub, that file does not accept 'textbox.text'.
Example:
Public Shared Sub AccountDeposit(ByVal value As Integer, ByVal AccountNumber As String, ByVal connection As SqlConnection)
Dim cmd As New SqlCommand("AccountDeposit", connection)
cmd.CommandType = Data.CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#AccountNumber", AccountNumber)
cmd.Parameters.AddWithValue("#Value", value)
cmd.ExecuteNonQuery()
End Sub
Here "AccountDeposit" is my stored procedure which i included in my sub.I want to do similar thing here but dont know how to include the text in textbox to sql statement
I have a page where a user fills in some text boxes which get saved to a SQL database using a Submit button. The page also contains a button that allows them to upload attachments. If the user uploads an attachment BEFORE clicking the submit button to save the other data, the values in the text boxes are cleared once the upload routine executes the Response.Redirect(Request.Url.AbsoluteUri). I have tried saving the values I want to restore into the Session, but I don't seem to be able to restore them. The debugger shows they are there, but once the Response.Redirect is executed, the next lines are never executed. I'm brand new to ASP.NET, so I may just be missing something obvious. Here is the code for the upload procedure:
Protected Sub Upload(sender As Object, e As EventArgs) Handles btnUpload.Click
Session("Phone") = txtPhone.Text
Session("Name") = txtName.Text
Session("Email") = txtEmail.Text
Session("StartDate") = txtStartDate.Text
Session("EndDate") = txtEndDate.Text
Session("Subject") = txtSubject.Text
Session("Description") = txtDescription.Value
Dim filename As String = Path.GetFileName(FileUpload1.PostedFile.FileName)
Dim contentType As String = FileUpload1.PostedFile.ContentType
Using fs As Stream = FileUpload1.PostedFile.InputStream
Using br As New BinaryReader(fs)
Dim bytes As Byte() = br.ReadBytes(fs.Length)
Dim constr As String = ConfigurationManager.ConnectionStrings("EngineeringRequestsConnectionString").ConnectionString
Using con As New SqlConnection(constr)
Dim query As String = "insert into Attachments values (#id, #Name, #ContentType, #Data)"
Using cmd As New SqlCommand(query)
cmd.Connection = con
cmd.Parameters.Add("#id", SqlDbType.Int).Value = nextId
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = filename
cmd.Parameters.Add("#ContentType", SqlDbType.NVarChar).Value = contentType
cmd.Parameters.Add("#Data", SqlDbType.VarBinary).Value = bytes
con.Open()
cmd.ExecuteNonQuery()
con.Close()
End Using
End Using
End Using
End Using
hasUpload = True
Response.Redirect(HttpContext.Current.Request.Url.AbsoluteUri)
BindGrid()
End Sub
The BindGrid() procedure attempts to restore the values from Session but never gets executed.
If hasUpload Then
txtPhone.Text = CType(Session("Phone"), String)
txtName.Text = CType(Session("Name"), String)
txtStartDate.Text = CType(Session("StartDate"), String)
End If
This is my first post on SO. I apologize if in advance if it is not clear enough.
If you are new to ASP.NET webforms it's probably worth checking out the Page Lifecycle as this dictates the order in which events are fired when a page is loaded. The issue is that you are effectively taking the user from page A to page B but expecting them to see results on page A.
In your method
Protected Sub Upload(sender As Object, e As EventArgs) Handles btnUpload.Click
.. skip ..
Response.Redirect(HttpContext.Current.Request.Url.AbsoluteUri)
BindGrid()
When you call Response.Redirect() the browser will redirect to a new page (e.g. from A -> B), this will start the page lifecycle over again, anything that happens after Response.Redirect() won't be rendered. I think what is confusing you is that you are redirecting from (A -> A), however this will still cause the page to be reloaded.
One option is to call BindGrid() and reload the data from session in one of the page load events, or remove the call to Response.Redirect() all together and instead leave the page as-is.
Please have a look at the code below, which I have written as a test. It does not make the ASP.NET process grow too much:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
Dim Test As Integer
For Test = 0 To 1000000
Test1()
Next
Dim Test2 As String = "Test"
Catch ex As Exception
End Try
End Sub
Public Sub Test1()
Try
Dim objCommand As New SqlCommand
Dim strConString As String = "Data Source=IANSCOMPUTER;Initial Catalog=Test;Integrated Security=True"
Dim objCon As New SqlConnection
objCon.ConnectionString = strConString
objCon.Open()
objCommand.Connection = objCon
objCommand.CommandText = "select * from person "
Dim objDR As SqlDataReader = objCommand.ExecuteReader
If objDR.HasRows Then
Using objCon
End Using
End If
Catch ex As Exception
'I don't swallow exceptions.
End Try
End Sub
End Class
I am trying to detect a memory leak. I have found code similar to the above in the affected project. I notice that objCommand.dispose is not called. The project in question connects to an Oracle database and an SQL database. When connecting to an SQL database the above code is used. When connecting to an Oracle database Oracle.dataaccess.dll is used and the code looks different to reflect this.
My specific question is: if I avoid calling sqlcommand.dispose then will this cause a memory leak over time?
If a class has a Dispose method, that isn't getting called, then it is likely to be the source of a memory leak. Use Using, and it will call the Dispose method for you.
Your second example should look like the below, where all disposable object are wrapped in using blocks.
Dim strConString As String = "Data Source=IANSCOMPUTER;" +
"Initial Catalog=Test;Integrated Security=True"
Dim sqlStr as String = "select * from person "
Using objCon As New SqlConnection(strConString)
Using objCommand As New SqlCommand(sqlStr, objCon)
objCon.Open()
Using objDR As SqlDataReader = objCommand.ExecuteReader
If objDR.HasRows Then
End If
End Using
End Using
End Using
I made a basic program that connects and gets content from a table via SQL, it's working normally. What I want is; when connection losts via SQL Server or internet connection, it must continue to list items that it got before connection losts instead of giving "Connection Problem Error".
Code is like this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strSQL As String
Dim conn As New SqlConnection
conn.ConnectionString = baglan()
conn.Open()
strSQL = "SELECT * FROM Telefon_Otomasyon"
Dim da As New SqlDataAdapter(strSQL, conn)
Dim dset As New DataSet()
da.Fill(dset, "Telefon_Otomasyon")
Dim Hepsi As DataRow
For Each Hepsi In dset.Tables("Telefon_Otomasyon").Rows
Response.Write(Hepsi("Arayan") & "<br />")
Next
End Sub
Thanks!
What you can do is store your dataset in Session: (excuse my VB, i'm very rusty with it)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strSQL As String
Dim conn As New SqlConnection
conn.ConnectionString = baglan()
conn.Open()
strSQL = "SELECT * FROM Telefon_Otomasyon"
Dim da As New SqlDataAdapter(strSQL, conn)
Dim dset As New DataSet()
Try
da.Fill(dset, "Telefon_Otomasyon")
MyDataset = dset
Catch ex As SqlException
dset = MyDataset
End Try
Dim Hepsi As DataRow
For Each Hepsi In dset.Tables("Telefon_Otomasyon").Rows
Response.Write(Hepsi("Arayan") & "<br />")
Next
End Sub
Private Property MyDataset() As DataSet
Get
return Session("myDataset")
End Get
Set(ByVal value as DataSet)
Session("myDataset") = value
End Set
End Property
This is also a very basic example, it needs to be tidied up before you can use it in production code, i.e. you need to consider what to do if there is no dataset stored in Session (if it returns null). You may want to be a bit smarter than that and just store a specific table. Note that Session can expire though, so do some reading on it. This should be enough to steer you in the right direction.
Further note: if you want something a little less volatile than Session then you could try using the Cache instead.
I'm not sure I understand the problem here. While I'm not a VB-programmer it seems to me like once the page loads it will run the SQL query and then process that dataset.
If you reload the page and the SQL connection isn't working you will get an error that you'd need to handle somehow (not sure how VB exceptions work but I'm sure you can figure that out).
If you on the other hand mean that you want to get whatever data you can from a query that gets disconnected mid-query - I'd say that is pretty hard and only relevant for huge queries.