retrieving data from SQL in VB (part 2) - vb.net

I am trying to populate a listbox by retrieving data from a database through sql. I have asked this question earlier but i was using a different configuration and the one i'm using now isn't giving any results.
retrieving data in VB from SQL
That is my old post. I will now provide the code to the newer version of my attempt.
Imports System.Data.Sql
Imports System.Data.SqlClient
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim conn As New SqlConnection
conn.Open()
Dim comm As New SqlCommand("SELECT name FROM Table_1", conn)
Dim reader As SqlDataReader = comm.ExecuteReader
Dim dt As New DataTable
dt.Load(reader)
ListBox1.Items.Add(dt)
End Sub
End Class
If anyone would be willing to help me out i'd greatly appreciate it. If possible, use a practical approach when trying to enlighten me, as that works best.
edit 1
Imports System.Data.Sql
Imports System.Data.SqlClient
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim connString As String = "Data Source=THE_SHOGUNATE\SQLEXPRESS;Initial Catalog=le_database;Integrated Security=True"
Dim conn As New SqlConnection(connString)
conn.Open()
Dim comm As New SqlCommand("SELECT name FROM Table_1", conn)
Dim reader As SqlDataReader = comm.ExecuteReader
Dim dt As New DataTable
dt.Load(reader)
ListBox1.DataSource = dt
End Sub
End Class
With this code the listbox populates with 6 instances of "System.Data.DataRowView" strings, 6 being the number of items in my table. How do i get the actual values?

You missed the connectionString
If you want to populate list from DB there are many ways
With DataReader
Imports System.Data.Sql
Imports System.Data.SqlClient
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim connectionString As String = "Data Sourec=localhost;........."
Dim conn As New SqlConnection(connectionString)
conn.Open()
Dim comm As New SqlCommand("SELECT name FROM Table_1", conn)
Dim reader As SqlDataReader = comm.ExecuteReader
/* As it is not working i commented this
listBox1.ItemsSource = dt; // use this instead of ListBox1.Items.Add(dt)
//because Add event add only one item in the list.
*/
Dim i As Integer
i=0
while reader.read()
listbox1.Items.Add(dr(i).ToString);
i++
End While
End Sub
End Class
With DataTable
Imports System.Data.Sql
Imports System.Data.SqlClient
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim connectionString As String = "Data Sourec=localhost;........."
Dim conn As New SqlConnection(connectionString)
conn.Open()
// Create new DataAdapter
SqlDataAdapter a = new SqlDataAdapter("SELECT * FROM EmployeeIDs", c)
// Use DataAdapter to fill DataTable
DataTable dt = new DataTable();
a.Fill(dt);
ListBox1.DataSource = dt;
ListBox1.DataTextField = "name";
End Sub
End Class
EDIT:
Other parameters of connection string depends on your security and all that. You must see this link Connection strings for SQL Server 2008

Set the DisplayMember property after DataSource binding:
ListBox1.DataSource = dt
ListBox1.DisplayMember="name"

The last solution I saw should work, but there are a couple important best practices to keep in mind regarding SQL Server.
1) Avoid Select * whenever possible, instead name your columns explicitly. Select * causes SQL to perform extra work if you do not intend to pull down all the columns in the table. It's also not future-proof, since a dba could add a VARBINARY(MAX) column in the future, and populate it with gigs worth of blob data, This scenario would make your query as written slow down substantially and unnecessarily.
2) Always remember to close your SQLConnection when you're done with it. This will free up a SQL connection and resources.
if (cn.State != ConnectionState.Closed)
cn.Close();
Another cool trick is to use the USING directive which will dispose of the SqlConnection object when execution passes out of scope.
using (SqlConnection cn = new SqlConnection(sConnectionString))
{
if (cn.State != ConnectionState.Open)
cn.Open();
// add query code here.
if (cn.State != ConnectionState.Closed)
cn.Close();
}
don't forget to close your SqlDataReader after the read loop is complete.
if (!dr.IsClosed)
dr.Close();
I hope this helps.
Andre Ranieri

Related

i am currently getting this error, System.InvalidOperationException: 'Fill: SelectCommand.Connection property has not been initialized.'

Imports System.Data
Imports System.Data.OleDb
Imports System.Data.DataTable
Public Class Form1
Private Sub btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
Dim conn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Katlego\Documents\LoginDb.accdb")
Dim cmd As New OleDbCommand("select * from logintable where username1=#username1 and password1=#password1, conn")
cmd.Parameters.Add("#username1", oleDbType:=OleDbType.VarChar).Value = txtusername.Text
cmd.Parameters.Add("#password1", oleDbType:=OleDbType.VarChar).Value = txtpassword.Text
Dim adapter1 As New OleDbDataAdapter(cmd)
Using logintable As New DataTable
Dim unused = adapter1.Fill(logintable)
If logintable.Rows.Count <= 0 Then
MsgBox("error username or password")
Else
MsgBox("login sucessfull")
End If
End Using
End Sub
You need to open the connection first
conn.Open()
There's a typo when you are initializing cmd object. You include the conn object inside the connection string. So the cmd object is missing a connection object.
Dim cmd As New OleDbCommand("select * from logintable where username1=#username1 and password1=#password1, conn")
Should be:
Dim cmd As New OleDbCommand("select * from logintable where username1=#username1 and password1=#password1", conn)
It is usually a good idea to separate you user interface code (where you click buttons and show message boxes) from your database code.
Connections, Commands and DataAdapters need to be disposed so they can release their unmanaged resources. Using...End Using blocks will do this for us.
Since you only want to know if the record exits you can just get the count. You had a typo in your command text. The closing quote included the conn.
We don't need DataTable or DataAdapter. That single piece of data only requires an ExecuteScalar which returns an Object so we need the CInt.
Private Sub btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
If IsLoginValid(txtusername.Text, txtpassword.Text) Then
MsgBox("login sucessfull")
Else
MsgBox("error username or password")
End If
End Sub
Private Function IsLoginValid(uname As String, pword As String) As Boolean
Dim count As Integer
Using conn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Katlego\Documents\LoginDb.accdb"),
cmd As New OleDbCommand("select Count(*) from logintable where username1=#username1 and password1=#password1;", conn)
cmd.Parameters.Add("#username1", OleDbType.VarChar).Value = uname
cmd.Parameters.Add("#password1", OleDbType.VarChar).Value = pword
conn.Open()
count = CInt(cmd.ExecuteScalar)
End Using
If count = 1 Then
Return True
End If
Return False
End Function
There is still a big problem with the code. Passwords should NEVER be stored as plain text. They need to be salted and hashed but that is beyond the scope of this question.

How to fill a ComboBox using records from an Access database

I want to retrieve the data and display in a ComboBox but it's showing blank.
This is my code:
Imports System.Data.OleDb
Public Class frmAirwaybill
Private Sub frmAirwaybill_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim cm As OleDbCommand = New OleDbCommand("select acc_no from tblshipper order by acc_no")
cm.Connection = DBconnection()
Dim dr As OleDbDataReader = cm.ExecuteReader
Do While (dr.Read())
txtAccountNo.Items.Add(dr.Item("acc_no"))
Loop
dr.Close()
DBconnection.Close()
End Sub
End Class*
txtAccountNo is the ComboBox
What I want, when the form loads, is to load the accno from my database. How do I do that?
This is a screenshot showing the ComboBox with blank values:
My database connection is OK.
This is my connection on module file
Public Function DBconnection() As OleDbConnection
Dim con As New OleDb.OleDbConnection
Dim constring As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Application.StartupPath & "\SmartshipG2.mdb"
con = New OleDb.OleDbConnection(constring)
con.Open()
Return con
End Function
The first thing to note is that you haven't opened the connection. This is probably the root cause.
That said, you are better binding to the .DataSource of the ComboBox using a DataTable and setting the .DisplayMember and .ValueMember properties.
I would also consider implementing Using:
Sometimes your code requires an unmanaged resource, such as a file handle, a COM wrapper, or a SQL connection. A Using block guarantees the disposal of one or more such resources when your code is finished with them. This makes them available for other code to use.
Lastly, consider giving your ComboBox a better prefix. txt is often used for TextBox controls. I use cmb whilst others may use cbx. So in this case cmbAccountNo seems a better fit.
With the changes you code would look something like this:
Dim dt As New DataTable
Using con As OleDbConnection New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Application.StartupPath & "\SmartshipG2.mdb"),
cmd As New OleDbCommand("SELECT [acc_no] FROM [tblshipper] ORDER BY [acc_no]", con)
con.Open()
dt.Load(cmd.ExecuteReader())
End Using
cmbAccountNo.DataSource = dt
cmbAccountNo.DisplayMember = "acc_no"
cmbAccountNo.ValueMember = "acc_no"

How to pass a parameter from Vb.net combobox to reportviewer?

I am using Visual Studio express 2013 and coding in VB.NET.
I have created a report in Reportbuilder 3.0 with a parameter (Plaasnaamprm).
I would like to pass a parameter to the report via a combobox on my windows application form.
When I run my apllication, I get the following error message on the reportviewer :
"The 'Plaasnaamprm' parameter is missing a value".
I have tried the approach described here : How can I pass parameter to Reportviewer?
Here is my code :
Imports System.Data.SqlClient
Imports System.Data.Sql
Imports Microsoft.Reporting.WinForms
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'SkeduleringDatabasisDataSet.Blokke' table. You can move, or remove it, as needed.
Me.BlokkeTableAdapter.Fill(Me.SkeduleringDatabasisDataSet.Blokke)
Dim Plaasnaamprm(0) As Microsoft.Reporting.WinForms.ReportParameter
Dim cn As New SqlConnection
cn.ConnectionString = My.Settings.SkeduleringDatabasisConnectionString
cn.Open()
Dim da As New SqlDataAdapter
Dim sql As New SqlCommand("select * from blokke order by plaasnaam ", cn)
Dim bs As New BindingSource
Dim blokke As New DataTable
Dim rds As New ReportDataSource("DataSet1", blokke)
da.SelectCommand = sql
da.Fill(blokke)
bs.DataSource = blokke
Plaasnaamprm(0) = New Microsoft.Reporting.WinForms.ReportParameter("Plaasnaamprm,combobox1.selectedvaue")
ReportViewer1.ProcessingMode = ProcessingMode.Local
ReportViewer1.LocalReport.ReportPath = "C:\Users\Administrator \Desktop\SKED PROGRAM\Skedulering_Mei_2015\Skeduleer2\Verslae\parskaartjies9.rdlc"
ReportViewer1.LocalReport.SetParameters(Plaasnaamprm)
ReportViewer1.LocalReport.DataSources.Add(rds)
ReportViewer1.RefreshReport()
End Sub
End Class
I am stumped, so any help would be much appreciated.
Regards
I think you are not passing the required value for the parameter.
try changing this:
Plaasnaamprm(0) = New Microsoft.Reporting.WinForms.ReportParameter("Plaasnaamprm,combobox1.selectedvaue")
to
Plaasnaamprm(0) = New Microsoft.Reporting.WinForms.ReportParameter("Plaasnaamprm",combobox1.selectedvalue)

ExecuteReader CommandText property has not been properly initialized

First of all sorry if some of the code isn't right. I'm still new to using sql on vb.net
I have the following code:
Imports MySql.Data.MySqlClient
Imports System.Data.SqlClient
Public Class Form1
Private Sub btnLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoad.Click
Dim objConn As MySqlConnection
Dim objDataset As New DataSet
Dim objDataAdapter As MySqlDataAdapter
Dim myCommand As MySqlCommand
Dim sqlConn As String
objConn = New MySqlConnection("server=localhost;userid=root;database=attendance_system")
myCommand = objConn.CreateCommand
objConn.Open()
Dim objReader As MySqlDataReader = myCommand.ExecuteReader
sqlConn = "SELECT student_name FROM profile"
objDataAdapter = New MySqlDataAdapter(sqlConn, objConn)
objDataAdapter.Fill(objDataset, "profile")
MsgBox("The Connection is Now 'OPEN'")
objReader.Read()
TextBox1.Text = objReader("student_name")
objReader.Close()
objConn.Close()
End Sub
End Class
I am using MySQL connector via vb.net in phpmyadmin and have set a database with records.
The connection string is working, but my problem is when I try to click the button to load the data in the textbox, I keep getting:
The CommandText property has not been properly initialized."
The error is on this line:
"Dim objReader As MySqlDataReader = myCommand.ExecuteReader"
I've tried a lot of fixes that I've found on this site and the others as well.
This is the problem:
Dim objReader As MySqlDataReader = myCommand.ExecuteReader
sqlConn = "SELECT student_name FROM profile"
You're declared the SQL after you've tried executing the query (and even then you don't set it as the SQL for the command). How would you expect that to work? Additionally, sqlConn is a very strange name for a variable declaring the SQL - I'd expect it to be a connection.
It looks like you're trying to mix too very different ways of fetching data:
Reading directly from the reader
Filling a DataSet with a data adapter
You shouldn't be mixing them like that. Work out which you actually want to do, take out all the code related to the other style, and then make sure you're doing everything in a sensible order.
From MySqlCommand Class and the example given as
Public Sub ReadMyData(myConnString As String)
Dim mySelectQuery As String = "SELECT * FROM Test.Dept"
Dim myConnection As New MySqlConnection(myConnString)
Dim myCommand As New MySqlCommand(mySelectQuery, myConnection)
myConnection.Open()
Dim myReader As MySqlDataReader = myCommand.ExecuteReader()
Try
While myReader.Read()
Console.WriteLine(myReader.GetInt32(0).ToString() + ", " _
+ myReader.GetString(1))
End While
Finally
' always call Close when done reading.
myReader.Close()
' always call Close when done with connection.
myConnection.Close()
End Try
End Sub
Your command object is missing the select statement.

Binding data to a DataGridView

I have a bit of code which loads data from a stored procedure in MS SQL Server and then loads the data into a DataGridView, which works fine. What I want is for the code that connects / loads the data to sit in my Database class and then everything associated with the DataGridView to be stored in my Form but I am having problems passing the contents of the BindingSource over to the Form from the Database class.
Form1 code:
Public Class Form1
Dim myDatabaseObj As New Class1()
Dim bindingSource1 As New BindingSource()
Dim connectString As New SqlConnection
Dim objDataAdapter As New SqlDataAdapter
Dim table As New DataTable()
Dim tabletest As New DataTable()
Private Sub loadCompanyList()
Try
Me.dgv_CompanyList.DataSource = Me.bindingSource1
getCompanyList()
Catch ex As NullReferenceException
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
loadCompanyList()
End Sub
End Class
When I try place the getCompanyList() in a class and then create a new object that references the Form() it does not seem to return any value from the table to the MyForm.BindingSource1.Datasource meaning my DataGridView displays no data.
Database class code:
.....
Private Sub getCompanyList()
Try
Dim myForm as new Form()
connect_Transaction_Database()
objDataAdapter.SelectCommand = New SqlCommand()
objDataAdapter.SelectCommand.Connection = connectString
objDataAdapter.SelectCommand.CommandText = "sp_GetCompanyList"
objDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure
Dim commandBuilder As New SqlCommandBuilder(Me.objDataAdapter)
Dim table As New DataTable()
table.Locale = System.Globalization.CultureInfo.InvariantCulture
Me.objDataAdapter.Fill(table)
**MyForm.bindingSource1.DataSource = table**
Catch ex As DataException
MsgBox(ex.Message)
Catch ex As NullReferenceException
MsgBox(ex.Message)
End Try
disconnect_Transaction_Database()
End Sub
This question has just been bumped by the Community user so I thought I would provide an answer which may help others in the future.
Firstly, I would consider implementing Using:
Managed resources are disposed of by the .NET Framework garbage collector (GC) without any extra coding on your part. You do not need a Using block for managed resources. However, you can still use a Using block to force the disposal of a managed resource instead of waiting for the garbage collector.
Secondly, you don't need to use a SqlDataAdapter. Instead you can load a DataTable using the SqlCommand class and return that. I would also contain the SqlConnection in the method rather than having it opened and closed in a different one.
Your code would look something like this:
Form1 code:
Public Class Form1
Private Sub loadCompanyList()
Dim myDatabase As New Database
Me.dgv_CompanyList.DataSource = myDatabase.getCompanyList()
End Sub
End Class
Database code:
Public Class Database
Public Function getCompanyList() As DataTable
Dim dt As New DataTable
Using con As New SqlConnection(connectionString),
cmd As New SqlCommand("sp_GetCompanyList", con) With {.CommandType = CommandType.StoredProcedure}
con.Open()
dt.Load(cmd.ExecuteReader())
End Using
Return dt
End Function
End Class
You want getCompanyList to be a function, which returns a DataTable. Then, forget the BindingSource (if the DataGridView is read-only) and set the DataSource property to the function:
Me.dgv_CompanyList.DataSource = getCompanyList
I would suggest you make the GetCompanyList method into a Function that returns the DataTable filled by the SqlDataAdapter. There's no real reason this Sub should have a dependency on the form. Instead a method in the form could call this to get the DataTable and then perform the binding.
Public Function GetCompanyList() As DataTable
...
...
Dim table As New DataTable()
table.Locale = System.Globalization.CultureInfo.InvariantCulture
Me.objDataAdapter.Fill(table)
Return table
...
...