Database Connection is Not Ending - vb.net

I have the following code to insert some data from a GridView to a oracle database.
Protected Sub btnInsert_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnInsert.Click
Dim con = New OleDbConnection("Data Source=sml2; User ID=sfpl; Password=a; provider=OraOLEDB.Oracle")
con.Open()
For Each gvRow As GridViewRow In GridView1.Rows
Dim trndate As Date = ddlTrnDte.SelectedValue
Dim ZoneNo As Integer = ddlZone.SelectedValue
Dim DocNo As TextBox = CType(gvRow.FindControl("txtDocNo"), TextBox)
Dim VehCod As DropDownList = CType(gvRow.FindControl("ddlVeh"), DropDownList)
Dim CircleNo As DropDownList = CType(gvRow.FindControl("ddlCircle"), DropDownList)
Dim Contractor As DropDownList = CType(gvRow.FindControl("ddlContractor"), DropDownList)
Dim Supplier As DropDownList = CType(gvRow.FindControl("ddlSupplier"), DropDownList)
Dim NetWt As TextBox = CType(gvRow.FindControl("txtNetWt"), TextBox)
Dim Rate As TextBox = CType(gvRow.FindControl("txtRate"), TextBox)
Dim SNF As TextBox = CType(gvRow.FindControl("txtSNF"), TextBox)
Dim FAT As TextBox = CType(gvRow.FindControl("txtFAT"), TextBox)
Dim LR As TextBox = CType(gvRow.FindControl("txtLR"), TextBox)
Dim TS As TextBox = CType(gvRow.FindControl("txtTS"), TextBox)
'Create Connection
Dim cmd As OleDbCommand = New OleDbCommand("Insert into MLK_02_01 (TRN_DTE,ZONE_NO,CIRCLE_NO,CNT_NO,DOC_NO,SUP_COD,VEH_NUM,NET_WEIGHT,Q_SNF,Q_FAT,Q_LR,Q_TS,RATE,veh_cod) VALUES (:TRN_DTE,:ZONE_NO,:CIRCLE_NO,:CNT_NO,:DOC_NO,:SUP_COD,:VEH_NUM,:NET_WEIGHT,:Q_SNF,:Q_FAT,:Q_LR,:Q_TS,:RATE,:veh_cod)", con)
cmd.Parameters.Clear()
'TrnDate
cmd.Parameters.Add(":trn_dte", (OleDb.OleDbType.Date))
cmd.Parameters(":trn_dte").Value = DateTime.Now()
cmd.Parameters(":trn_dte").Value = ddlTrnDte.SelectedValue
cmd.Parameters.AddWithValue(":ZONE_no", ZoneNo)
cmd.Parameters.AddWithValue(":CIRCLE_no", CircleNo.SelectedValue)
cmd.Parameters.AddWithValue(":CNT_no", Contractor.SelectedValue)
cmd.Parameters.AddWithValue(":Doc_No", DocNo.Text)
cmd.Parameters.AddWithValue(":sup_cod", Contractor.SelectedValue)
cmd.Parameters.AddWithValue(":Veh_num", VehCod.SelectedItem.Text)
cmd.Parameters.AddWithValue(":NET_WEIGHT", NetWt.Text)
cmd.Parameters.AddWithValue(":Q_SNF", SNF.Text)
cmd.Parameters.AddWithValue(":Q_FAT", FAT.Text)
cmd.Parameters.AddWithValue(":Q_LR", LR.Text)
cmd.Parameters.AddWithValue(":Q_TS", TS.Text)
cmd.Parameters.AddWithValue(":rate", Rate.Text)
cmd.Parameters.AddWithValue(":veh_cod", VehCod.SelectedValue)
cmd.ExecuteNonQuery()
Label1.Text = "All Records are Saved Successfully"
con.Close()
btnInsert.Enabled = False
Next
End Sub
Data is inserted into database fine but when the form is closed the database connection does not end. I need help in ending the database session to eliminate further communication errors.

You mention it's a page, so I'm assuming this is an ASP page.
IIS has database connection pooling enabled by default. This means that even though your code closed your connection, IIS maintains a connection in order to make the next query from the next request execute faster.
To disable connection pooling, in your database connection string add this:
Pooling=false
New OleDbConnection("Data Source=sml2; User ID=sfpl; Password=a; provider=OraOLEDB.Oracle; Pooling=false")
Also, after your execute change to this:
cmd.ExecuteNonQuery()
cmd.Dispose()
After the con.Close():
con.Close()
con.Dispose()
and that should dispose the command and connection objects.

Related

Validating user input in a textbox in Winforms with values in the database

I have a windows form page with a textbox. The user needs to enter a "Code" into the textbox and upon a button click a validation should be done. Upon validating that this code exists in the database table a new page should be loaded which will contain details associated with this particular code like the year it was added, the document name, file path etc.
This is my first time programming in VB and I am not entirely familiar with the validation process and how the validation should be done against the database (I am using SQL Server).This is what I have until now:
Private Sub EnterClick_Click(sender As Object, e As EventArgs) Handles EnterClick.Click
Dim oRij As New NICOCrypt.Rijndael
Dim cnn As New SqlClient.SqlConnection(oRij.NICO_RijndaelManaged_Decrypt(ConfigurationManager.AppSettings("ConnectionString")))
Dim cmd As New SqlClient.SqlCommand
Dim oFiles As SqlClient.SqlParameter
cmd.CommandType = CommandType.StoredProcedure
Dim valueExistsInDB As Boolean = CBool(CInt(cmd.ExecuteScalar()) > 0)
cnn.Close()
If valueExistsInDB = True AndAlso txtCode.Text IsNot Nothing Then
End If
End Sub

Adding associated double values from database when checkedlistbox item is selected

Edited
Hi I have this program where I need to display the sum of the values when read from the database. I tried something like this:
Dim selec As String
Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\rose&mike\Desktop\DbSysDel3\salondbaccess.accdb")
Dim dt2 As New DataTable
selec = ""
con.Open()
For Each incheck In chcklstbx1.CheckedIndices
Dim valName As String
valName = chcklstbx1.Items.Item(incheck).ToString
Dim sqlstr2 As String = "SELECT Service_Fee FROM Service_Types WHERE [Service_Name] = '" & valName & "'"
Dim cmd As New OleDbCommand(sqlstr2, con)
Dim sum As Double = 0
Dim rdr As OleDbDataReader = cmd.ExecuteReader
If rdr.HasRows Then
While rdr.Read
selec += "P" + rdr("Service_Fee").ToString & ControlChars.NewLine
sum = sum + rdr("Service_Fee")
End While
End If
lblFees.Text = selec
lblTotal.Text = sum.ToString
rdr.Close()
Next
con.Close()
But all it does is display the values I want to add one by one when checked.
Here's an example of how this whole thing should be handled:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Using connection As New OleDbConnection("connection string here"),
adapter As New OleDbDataAdapter("SELECT Name, Amount FROM MyTable", connection)
Dim table As New DataTable
adapter.Fill(table)
'Bind the DataTable to the CheckedListBox.
'Normally the DataSource should be set last but, in my experience, that can cause problems with a CheckedListBox.
With CheckedListBox1
.DataSource = table
.DisplayMember = "Name"
.ValueMember = "Amount"
End With
End Using
End Sub
Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
'Get all the currently checked items.
Dim checkedItems = CheckedListBox1.CheckedItems.Cast(Of DataRowView)().ToList()
'Get the item that is being checked or unchecked.
Dim currentItem = DirectCast(CheckedListBox1.Items(e.Index), DataRowView)
If e.NewValue = CheckState.Checked Then
'The current item is being checked so add it to the list.
checkedItems.Add(currentItem)
Else
'The current item is being unchecked so remove it from the list.
checkedItems.Remove(currentItem)
End If
'Sum the Amounts from each checked item.
Dim sum = checkedItems.Sum(Function(drv) CDec(drv("Amount")))
'Use sum here.
'...
End Sub
You get all the data up front, including all the text to display and all the associated numeric values. That data can be bound to the CheckedListBox as a DataTable, keeping it all packaged together.
Each time the user checks or unchecks an item in the list, you perform the calculation based on the data you already have. No need to go back to the database.
The important thing to note about the ItemCheck event is that it is raised BEFORE the item is checked or unchecked. That's why the code needs to ad the current item, or remove it from, the list of checked items.
When you bind a DataTable, each bound item is a DataRowView, i.e. an item from the table's DefaultView. You get all the checked DataRowView items, get their numeric value and sum them. Note that I've used a LINQ query to calculate the sum succinctly but you could use a loop if you wanted to, e.g.
Dim sum As Decimal = 0D
For Each drv In checkedItems
sum += CDec(drv("Amount"))
Next

Combobox - display 2 Datatable columns

I created multiple-column drop-down list for a combobox from a DataTable, and now I want to display both columns in it too. So far only 1 column is displayed (with DisplayMember property). So basically I want Autocomplete with both columns displayed in combobox. I would be satisfied with displaying 2nd column in Textbox next to combobox too, but It must work as Autocomplete (when selected index changes, display value changes too). I need this because both Datable values (Name & Surname) will be added in another DB table together, and for user to see both values in same place.
EDITED:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim SQL As String = "SELECT ID,Name ||' ' || Surname as FullName from MyTable"
Dim dtb As New DataTable()
dtb.Columns.Add("Name", System.Type.GetType("System.String"))
dtb.Columns.Add("Surname", System.Type.GetType("System.String"))
Using con As OracleConnection = New OracleConnection("Data Source=MyDB;User Id=Lucky;Password=MyPassword;")
Try
con.Open()
Using dad As New OracleDataAdapter(SQL, con)
dad.Fill(dtb)
End Using
Combobox1.DataSource = dtb
Combobox1.DisplayMember = "FullName"
Combobox1.ValueMember= "ID"
con.Close()
Catch ex As Exception
'MessageBox.Show(ex.Message)
Finally
con.Dispose()
End Try
End Using
End Sub
And drawing line between combobox columns:
Private Sub Combobox1_DrawItem(sender As Object, e As DrawItemEventArgs) Handles Combobox1.DrawItem
e.DrawBackground()
Dim drv As DataRowView = CType(Combobox1.Items(e.Index), DataRowView)
Dim id As String = drv("Name").ToString()
Dim name As String = drv("Surname").ToString()
Dim r1 As Rectangle = e.Bounds
r1.Width = r1.Width / 2
Using sb As SolidBrush = New SolidBrush(e.ForeColor)
e.Graphics.DrawString(id, e.Font, sb, r1)
End Using
Using p As Pen = New Pen(Color.AliceBlue)
e.Graphics.DrawLine(p, r1.Right, 0, r1.Right, r1.Bottom)
End Using
Dim r2 As Rectangle = e.Bounds
r2.X = e.Bounds.Width / 2
r2.Width = r2.Width / 2
Using sb As SolidBrush = New SolidBrush(e.ForeColor)
e.Graphics.DrawString(name, e.Font, sb, r2)
End Using
End Sub
Any suggestions ? Thanks in advance !!
Checkout this answer: https://stackoverflow.com/a/5570901/6550457
It suggests:
comboBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
comboBox1.AutoCompleteSource = AutoCompleteSource.ListItems;
Only way to achieve all is to add another combobox and bind him to same datatable. This way when you select item from combobox you see both values in them. Autocomplete works too. Doing everything in same combobox is not good, displayed text is too wide, doesn't look good.

Asp.net Button disable value from Sql field

The title may not be the best description but i would like help with having the button be disabled depending on which user click on it.
I know I should put the connection string in the web.config and I will but I'm not getting this button to work.
The HasRows yest looks if there is a row but i might do this wrong.
I have 3 rows in the table and with only one row = 'reports' all 3 users can still click the Button?
Can anyone help me here?
Protected Sub LeftMenuBarReportsButton_Click(sender As Object, e As System.EventArgs) Handles LeftMenuBarReportsButton.Click
Dim sqlconn As New SqlConnection
Dim sqCmd As New SqlCommand
Dim sqlreader As SqlDataReader
sqlconn.ConnectionString = "server = ....;Database=......;User ID=......;Password=...." 'SQL Connection String
sqCmd.Connection = sqlconn
sqlconn.Open()
sqCmd.CommandText = "SELECT UserID,Password,Role FROM UserCredentials WHERE Role = 'Reports'"
sqlreader = sqCmd.ExecuteReader
If sqlreader.HasRows Then
Response.Redirect("Reports.aspx")
Else
Dim click As Button = sender
click.Enabled = False
LeftMenuBarReportsButton.BackColor = Drawing.Color.Red
LeftMenuBarReportsButton.Text = "Access Denied"
End If
sqlreader.Close()
sqlconn.Close()

Populating Listbox with Data from DataGridView

I've got 2 forms. Form A has a listbox and a Combobox. Form B has a DataGridView. In my A, my combobox is meant to represent groups for a task. e.g. Inbox, Important etc. So whenever I select an item from the comobobox e.g. I select the "Inbox" Item the DataGridViewer will sort all the rows which contain "Inbox" in one of the columns. This all works fine. I can view the sorted data.
To Load my data into the DataGridView I use:
Dim ds As DataSet
Dim dataset1 As New DataSet("datasetTasks")
Dim table1 As New DataTable("tableTask")
Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ds = CreateDataset()
frm_Tasks.DataGridView1.DataSource = ds.Tables("tableTask")
LoadFromXMLfile("C:\Users\Beta4K\Documents\Tasks.FILE")
For Each dr As DataRow In ds.Tables(0).Rows
ListBox1.Items.Add(dr("TaskName").ToString())
Next
End Sub
Private Sub LoadFromXMLfile(filename As String)
If System.IO.File.Exists(filename) Then
Dim xmlSerializer As XmlSerializer = New XmlSerializer(ds.GetType)
Dim readStream As FileStream = New FileStream(filename, FileMode.Open)
ds = CType(xmlSerializer.Deserialize(readStream), DataSet)
readStream.Close()
frm_Tasks.DataGridView1.DataSource = ds.Tables("tableTask")
Else
MsgBox("file not found! add data and press save button first.", MsgBoxStyle.Exclamation, "")
End If
End Sub
Private Function CreateDataset() As DataSet
table1.Columns.Add("TaskID")
table1.Columns.Add("TaskName")
table1.Columns.Add("TaskMessage")
table1.Columns.Add("TaskDate")
table1.Columns.Add("TaskTime")
table1.Columns.Add("TaskGroup")
dataset1.Tables.Add(table1)
Return dataset1
End Function
Here's the code for my Combobox:
ListBox1.Items.Clear()
Dim dv As New DataView(ds.Tables("tableTask"))
dv.RowFilter = "TaskGroup = '" + ComboBox1.SelectedItem + "'"
frm_Tasks.DataGridView1.DataSource = dv.ToTable("tableTask")
For Each dr As DataRow In ds.Tables(0).Rows
ListBox1.Items.Add(dr("TaskName").ToString())
Next
What this is meant to do is that it clears the listbox, and then reloads the items into the listbox from reading all the data in the DataGridViewer. Since it's already sorted all it has to do is add the items but it doesn't. Instead it just adds all the items regardless of the filter.
Can someone help me.
You loop over the datatable while you need to loop over the dataview
For Each dr As DataRowView In dv
ListBox1.Items.Add(dr("TaskName").ToString())
Next