I have a program that uses either a SQL Server database or a MS Access database.
I'm trying to figure out a way to use either of the databases with the same code. As an example you would do the folowing depending on what DB you're using:
SQL Server:
Using cmd As SqlCommand = New SqlCommand(SQLQuery, Connection)
Using rs As SqlDataReader = cmd.ExecuteReader
Do While rs.Read
' Do something
Loop
End Using
End Using
MS Access:
Using cmd As OleDbCommand= New OleDbCommand(SQLQuery, Connection)
Using rs As OleDbDataReader= cmd.ExecuteReader
Do While rs.Read
' Do something
Loop
End Using
End Using
In my case , I could implement something like this:
Dim rs As New Object
Dim con As Object
Dim cmd As Object
If SQL-Server Then
con = TryCast(conSQL-Server, SqlConnection)
cmd = New SqlCommand
rs = TryCast(rs, SqlDataReader)
Else
con = TryCast(conMS-Access, OleDb.OleDbConnection)
cmd = New OleDb.OleDbCommand
rs = TryCast(rs, OleDb.OleDbDataReader)
End If
Try
With cmd
.Connection = con
.CommandText = SQLQuery
rs = .ExecuteReader
End With
Do While rs.Read
' Do something
Loop
Catch ex As Exception
' Handle Error
Finally
If Not rs Is Nothing Then
If Not rs.IsClosed Then rs.Close()
rs.Dispose()
End If
cmd.Dispose()
End Try
but that's a lot of hassle. It would be nice if you could create a custom type to do something like:
If SQL-Server Then
DBCommand = SqlCommand
DBReader = SqlDataReader
Else
DBCommand = OleDbCommand
DBReader = OleDbDataReader
End
Using cmd As DBCommand = New DBCommand(SQLQuery, connection)
Using rs As DBReader = cmd.ExecuteReader
Do While rs.Read
' Do something
Loop
End Using
End Using
Any ideas?
I discovered the answer:
Dim con As IDbConnection
If SQL-Server Then
con = conSQL-Server
Else
con = conMS-Access
End If
Using cmd As IDbCommand = con.CreateCommand()
cmd.CommandText = SQLQuery
Using rs As IDataReader = cmd.ExecuteReader
Do While rs.Read()
' Do something
Loop
End Using
End Using
It's too bad CreateCommand doesn't take parameters.
Related
In the Database, I used an assigned ProgName = varchar,MaleCuteOff = int,FemaleCutOff=int, and I'm trying to collect User input for the values, but I'm getting an Error
Conversion from string "INSERT INTO CutOff_Point((ProgN" to type
integer is not valid.
Sub save()
Dim query As String = "INSERT INTO CutOff_Point (ProgName, MaleCutOff, FemaleCutOff) VALUES (#colProg, #colMale, #colFemale)"
Using con As New SqlConnection("Data Source=.;Initial Catalog=UEW_ADMISSION_CHEAKER;Integrated Security=True")
Using com As New SqlCommand()
With com
.Connection = con
.CommandType = query
.Parameters.AddWithValue("#colProg", cmbProg.SelectedItem.ToString)
.Parameters.AddWithValue("#colMale", txtMaleCut.Text.ToString)
.Parameters.AddWithValue("#colFemale", txtFemaleCut.Text.ToString)
End With
Try
con.Open()
com.ExecuteNonQuery()
Catch ex As SqlException
MessageBox.Show(ex.Message.ToString(), "Saving data Not Complete")
End Try
End Using
End Using
End Sub
This:
.CommandType = query
should be setting Commandtext, not CommandType. Why set those properties like that in the first place, when you can use the constructor?
Using com As New SqlCommand(query, con)
I am a beginner and really need help. I want to display data from the database and assign the values to the textboxes and a combobox on a form, but I get this error
Incorrect syntax near "="
It appears is on this line
myreader = cmd.ExecuteReader
Please - any help?
Sub ref()
Dim conn As New SqlConnection
conn.ConnectionString = ("Data Source=.;Initial Catalog=UEW_ADMISSION_CHEAKER;Integrated Security=True")
conn.Open()
Dim strsql As String
strsql = "SELECT ProgName,MaleCuteOff,FemaleCutOff from CutOff_Point where ProgName=" + cmbCourse.SelectedItem + ""
Dim cmd As New SqlCommand(strsql, conn)
Dim myreader As SqlDataReader
myreader = cmd.ExecuteReader
myreader.Read()
txtFemale.Text = myreader("FemaleCutOff")
txtMale.Text = myreader("MaleCuteOff")
conn.Close()
End Sub
You should always use SQL parameters to pass parameters to SQL - it avoids embarrasing problems like single quotes breaking the query and deliberate SQL injection attacks.
It's probably best to make sure that there is a selected value before trying to use it.
Some things, e.g. database connections, use "unmanaged resources" and it is necessary to use the Dispose() method to make sure that things are cleaned up afterwards. The Using statement is a convenient way to get the computer to take care of that for you.
I didn't see a need for the query to return the value that was passed to it (ProgName).
You will need to adjust the .SqlDbType and .Size to match the database column.
Option Strict On
' ... other code
Sub Ref()
If cmbCourse.SelectedIndex >= 0 Then
Dim sql As String = "SELECT MaleCuteOff, FemaleCutOff FROM CutOff_Point WHERE ProgName = #ProgName"
Dim connStr = "Data Source=.\;Initial Catalog=UEW_ADMISSION_CHEAKER;Integrated Security=True"
Using conn As New SqlConnection(connStr),
cmd As New SqlCommand(sql, conn)
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "#ProgName", .SqlDbType = SqlDbType.VarChar, .Size = 99, .Value = cmbCourse.SelectedItem})
conn.Open()
Dim rdr As SqlDataReader = cmd.ExecuteReader()
If rdr.HasRows Then
rdr.Read()
txtFemale.Text = rdr.GetInt32(0).ToString()
txtMale.Text = rdr.GetInt32(1).ToString()
End If
End Using
End If
End Sub
P.S. Shouldn't UEW_ADMISSION_CHEAKER be UEW_ADMISSION_CHECKER? It's best to have things spelt correctly as it is easier to type them.
First of all this Block of Code is not OK. You could use :
Using....End Using Method.
SqlCommand.Parameters Property for security issues.
Connection Strings and Configuration Files for security issues.
Allow me to rewrite your Code using the above methods.
Private Sub RetrieveAndDisplayCutOff()
Dim sbMale As New StringBuilder
Dim sbFemale As New StringBuilder
Dim strsql As String =
"SELECT MaleCutOff,FemaleCutOff FROM CutOff_Point WHERE ProgName = #ComboItem"
Using conn As New SqlConnection("Data Source=.;Initial Catalog=UEW_ADMISSION_CHEAKER;Integrated Security=True"),
CMD As New SqlCommand(strsql, conn)
CMD.Parameters.Add("#ComboItem", SqlDbType.VarChar).Value = ComboBox1.SelectedItem.ToString
conn.Open()
Using MyReader As SqlDataReader = CMD.ExecuteReader
While MyReader.Read 'Returns False if no more rows
'OP mentioned in comments that these fields were int
sbMale.AppendLine(MyReader.GetInt32(0).ToString)
sbFemale.AppendLine(MyReader.GetInt32(1).ToString)
End While
End Using
End Using
txtMale.Text = sbMale.ToString
txtFemale.Text = sbFemale.ToString
End Sub
I want to capture count of record to a variable but code is not working. Please assist
Dim PrevRgAPAC As Integer
Dim con As New SqlConnection
Dim cmd As New SqlCommand
Dim rd As SqlDataReader
con.ConnectionString = "Data Source=XXXXXXXXXXX; initial catalog=XXXXXXXXXXXX; Integrated Security=true"
cmd.Connection = con
con.Open()
cmd.CommandText = "select count(record) from tblKPI where user_region='APAC' AND payroll_month='February'"
rd = cmd.ExecuteReader
If rd.HasRows Then
rd.Read()
PrevRgAPAC = rd.Item("exec")
Else
MsgBox("Not Found")
End If
Thank you
Try to use SqlCommand.ExecuteScalar Method:
PrevRgAPAC = Convert.ToInt32(cmd.ExecuteScalar())
Assuming that PrevRgAPAC is the variable in which you want to store the value of count. So your code would look like this:
Dim PrevRgAPAC As Int32 = 0
Dim sql As String = "select count(record) from tblKPI where user_region='APAC' AND payroll_month='February'"
Using conn As New SqlConnection("Data Source=XXXXXXXXXXX; initial catalog=XXXXXXXXXXXX; Integrated Security=true")
Dim cmd As New SqlCommand(sql, conn)
Try
conn.Open()
PrevRgAPAC = Convert.ToInt32(cmd.ExecuteScalar())
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using
I'm trying to populate a combobox with data from SQL Server. This is my code so far. There are asterisks around the errors. Also, ignore the comments.
Private Sub frmOriginal_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim connetionString As String = Nothing
Dim sqlcon As SqlConnection
Dim command As SqlCommand
Dim adapter As New SqlDataAdapter()
Dim ds As New DataSet()
Dim i As Integer = 0
Dim sql As String = Nothing
connetionString = "Data Source = RENEE\SQLEXPRESS;Initial Catalog=Stocks;Integrated Security = True"
sql = "select * from TickerSymbol"
sqlcon = New SqlConnection(connetionString)
Try
sqlcon.Open()
command = New SqlCommand(sql, sqlcon)
adapter.SelectCommand = command
adapter.Fill(ds)
adapter.Dispose()
command.Dispose()
sqlcon.Close()
cboID.DataSource = ds.Tables(0)
cboID.ValueMember = "TickerSymbol"
cboID.DisplayMember = "TickerSymbol"
Catch ex As Exception
'MessageBox.Show("Can not open connection ! ")'
End Try
End Sub
Private Sub cboID_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboID.SelectedIndexChanged
Dim dr As SqlDataReader
Dim command As New SqlCommand *(queryString, connection)*
Dim dataReader As SqlDataReader = command.ExecuteReader()
Dim sqlcon As SqlConnection
Dim cmd As SqlCommand
sqlcon = New SqlConnection
sqlcon.ConnectionString = "Data Source = RENEE\SQLEXPRESS;Initial Catalog=Stocks;Integrated Security = True"
Try
sqlcon.Open()
cmd = New SqlCommand
cmd.CommandText = " select * from TickerSymbol where TickerSymbol = '" & cboID.Text & "'"
cmd = New SqlCommand(cmd.CommandText, sqlcon)
dr = cmd.ExecuteReader
While dr.Read()
'TxtID.Text = dr.GetInt32(0)'
'TxtSN.Text = dr.GetString(1)'
'TxtGender.Text = dr.GetString(2)'
'TxtPhone.Text = dr.GetInt32(3)'
'TxtAdrress.Text = dr.GetString(4)'
lblCompanyName.Text = dataReader.GetString(1)
lblPurchasePrice.Text = dataReader.GetSqlMoney(2)
lblQtyPurchased.Text = dataReader.GetInt32(3)
lblPurchaseDate.Text = dataReader.GetDateTime(4)
End While
sqlcon.Close()
Catch ex As SqlException
MessageBox.Show(ex.Message)
End Try
sqlcon.Dispose()
End Sub
Please use parameterized queries as this will format values properly e.g. apostrophes in text will escape properly with parameters while without you must handle them, dates will be formatted properly too. Code is much cleaner also.
Example, syntax for Framework 3.5 and higher. If a connection string is used more than once then consider placing it in a private variable or under My.Settings under project properties.
Using cn As New SqlConnection With {.ConnectionString = "Data Source = RENEE\SQLEXPRESS;Initial Catalog=Stocks;Integrated Security = True"}
Using cmd As New SqlCommand With {.Connection = cn, .CommandText = "select * from TickerSymbol where TickerSymbol = #TickerSymbol"}
cmd.Parameters.AddWithValue("#TickerSymbol", cboID.Text)
cn.Open()
Dim dr As SqlDataReader = cmd.ExecuteReader
If dr.HasRows Then
While dr.Read
'
'
'
End While
End If
End Using
End Using
After running the following sub (VS debugger), I try to detach the database in SSMS, but it shows the connection open still and won't let me detach. If I close program in debugger, the database shows no connections. I check the dataadapter's connection in the finally block and is shows closed. What gives
Private Function ClientMasterDBFiles(ByVal MasterClientDBConnection As String, ByVal DBName As String) As DataTable
Dim da As SqlDataAdapter
Dim ds As DataSet
Try
ds = New DataSet
da = New SqlDataAdapter
da.SelectCommand = New SqlCommand
With da.SelectCommand
.CommandType = CommandType.StoredProcedure
.Connection = New SqlConnection(MasterClientDBConnection)
.CommandText = "QT_DataSync_GetDBFileLocations"
.Parameters.Add(New SqlParameter("#DBName", SqlDbType.VarChar, 100))
.Parameters.Item("#DBName").Direction = ParameterDirection.Input
.Parameters.Item("#DBName").Value = DBName
.CommandType = CommandType.StoredProcedure
.CommandTimeout = 10
End With
da.Fill(ds)
If ds.Tables.Count > 0 Then
Return ds.Tables(0)
End If
Catch ex As Exception
m_ErrorLog.HandleException(ex)
Throw
Finally
If Not da Is Nothing Then da.Dispose()
If Not ds Is Nothing Then ds.Dispose()
da = Nothing
ds = Nothing
End Try
End Function
EDIT
I was wrong all along.
Your problem is that the .Net SqlClient classes pool connections.
You need to explicitly close the SqlCommand's Connection, like this:
If Not da Is Nothing Then da.SelectCommand.Connection.Close()
However, you should use a Using statement instead, like this:
Dim ds As DataSet
Try
Using da As SqlDataAdapter, _
da.SelectCommand = New SqlCommand, _
da.Connection = New SqlConnection(MasterClientDBConnection)
With da.SelectCommand
.CommandType = CommandType.StoredProcedure
.CommandText = "QT_DataSync_GetDBFileLocations"
.Parameters.Add(New SqlParameter("#DBName", SqlDbType.VarChar, 100))
.Parameters.Item("#DBName").Direction = ParameterDirection.Input
.Parameters.Item("#DBName").Value = DBName
.CommandType = CommandType.StoredProcedure
.CommandTimeout = 10
End With
da.Fill(ds)
If ds.Tables.Count > 0 Then
Return ds.Tables(0)
End If
End Using
Catch ex As Exception
m_ErrorLog.HandleException(ex)
Throw
End Try
Also, you shouldn't dispose the DataSet, since you're returning one of its tables.