This is probably an easy thing to do, but I'm only doing my first vb project so I'm not sure how to do this 100%, so apologies in advanced if the following problem is actually very simple.
Basically, what I need to do is, when loading a database table into an ultragrid, I need to retrieve the maximum integer that is stored in a field.
To explain this more clearly, each record in the database has it's own ID number, so I need to iterate each record and find the one with the highest ID number, and return the ID, so that this can then be used in other calculations.
I know that I can use SQL = SELECT MAX(supportID) FROM tblIncidents for example to retrieve the highest ID number stored in this table.
So, how do I go about declaring the result of this (so, the highest ID number) as variable so that I can firstly display it in a messagebox to prove to me that the query has worked, and secondly so that I can use the variable as means of using the ID throughout my code?
An example; This is the code to save a new record into the tblIncidents table.
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim incidentSolved As Boolean = False
If cboxSolved.Checked Then
incidentSolved = True
End If
If txtClientSave.Text = "" Then
MsgBox("Client name cannot be blank")
ElseIf rtbProblem.Text = "" Then
MsgBox("Problem cannot be blank")
ElseIf cboxSolved.Checked = True And rtbSolution.Text = "" Then
MsgBox("Please enter solution")
Else
database.SaveNewIncident(txtClientSave.Text, dtpStart.Value, dtpEnd.Value, rtbProblem.Text, dtpStartTime.Value, dtpEndTime.Value, cboxSolved.Checked, rtbSolution.Text, _con)
txtClientSave.Text = ""
rtbProblem.Text = ""
rtbSolution.Text = ""
dtpStart.Value = Date.Today
dtpEnd.Value = Date.Today
dtpStartTime.Value = DateTime.Now
dtpEndTime.Value = DateTime.Now
cboxSolved.Checked = False
End If
End Sub
Database function that is called
Public Shared Function SaveNewIncident(ByVal clientName As String, dateStart As Date, dateEnd As Date, ByVal incidentProblem As String, ByVal timeStart As String, ByVal timeEnd As String,
ByVal incidentSolved As Boolean, ByVal incidentSolution As String, _Con As OleDbConnection)
Dim tr As OleDbTransaction = Nothing
Try
tr = _Con.BeginTransaction()
Dim Dc As New OleDbCommand
Dc.Connection = _Con
Dc.CommandType = CommandType.Text
Dc.CommandText = "INSERT INTO dbo.tblIncidents VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"
Dc.Transaction = tr
Dc.Parameters.Add("#clientName", OleDbType.VarChar).Value = clientName
Dc.Parameters.Add("#dateStart", OleDbType.Date).Value = dateStart
Dc.Parameters.Add("#dateEnd", OleDbType.Date).Value = dateEnd
Dc.Parameters.Add("#incidentProblem", OleDbType.LongVarChar).Value = incidentProblem
Dc.Parameters.Add("#timeStart", OleDbType.VarChar).Value = timeStart
Dc.Parameters.Add("#timeEnd", OleDbType.VarChar).Value = timeEnd
Dc.Parameters.Add("#incidentSolved", OleDbType.Boolean).Value = incidentSolved
Dc.Parameters.Add("#incidentSolution", OleDbType.LongVarChar).Value = incidentSolution
Dc.ExecuteNonQuery()
tr.Commit()
MsgBox("Save successful")
Catch ex As Exception
mdInit.errorLog(ex.Message, ex.StackTrace)
MsgBox("Failed to save data, refer to error log")
tr.Rollback()
End Try
End Function
what you can do in VB.net is define a SQLcommand which will require a SQL connection attached to it - since your query returns a single value you will be able to execute it with ExecuteScalar to return a single value eg
Dim cmd AS New SqlClient.SQLCommand("SELECT MAX(billID) FROM tblRecurring",connectionString)
then
cmd.connection.open
and then
dim x as MaxId = cmd.executeScalar
and finish off with
cmd.connection.dispose
of course
Related
I am trying to do a SQL query that calculates the number of days between two dates from a database.
However an error occurs when I try to search for specific data from the database. Furthermore does anyone know how I could use the sql Query that counts how many days is between two dates in a calculation, which would use data from another table. I have a room type table which has a room price column, and a booking table where I have the arrival date and departure date how could I calculate the total price for the booking.
System.Data.SQLite.SQLiteException: 'unknown error
Insufficient parameters supplied to the command'
Here is what I have so far
Function GetDuration(ID As Integer, fname As String)
Dim dsql As String = "Select Cast ((
JulianDay(Replace(departuredate,'/','-'))
- JulianDay(Replace(arrivaldate,'/','-'))
) As Integer)
from booking INNER JOIN customers on customers.CustomerID = booking.BookingID
where booking.bookingid = #ID or customers.fname LIKE #Fname;"
Using con As New SQLiteConnection(ConStr)
Dim mycmd As New SQLiteCommand(dsql, con)
con.Open()
cmd.Parameters.Add("#Fname", DbType.String).Value = $"%{fname}%"
cmd.Parameters.Add("#ID", DbType.Int32).Value = ID
Dim value As Object = mycmd.ExecuteScalar()
txtdurationofstay = value
End Using
End Function
Private Sub IbtnSearch_Click(sender As Object, e As EventArgs) Handles ibtnBSearch.Click
If txtBookingSearchID.Text <> "" Then
Dim SearchID As Integer
If Int32.TryParse(txtBookingSearchID.Text, SearchID) Then
DgvBookings.DataSource = GetData("null", SearchID)
GetDuration(txtBookingSearchID.Text, "null")
Else
MessageBox.Show("Please enter a valid number in the Search box.")
End If
ElseIf txtBsearchFname.Text <> "" Then
DgvBookings.DataSource = GetData(txtBsearchFname.Text, 0)
GetDuration(0, txtBsearchFname.Text)
End If
End Sub
You defined mycmd here:
Dim mycmd As New SQLiteCommand(dsql, con)
but added the parameters to cmd and not to mycmd:
cmd.Parameters.Add("#Fname", DbType.String).Value = $"%{fname}%"
cmd.Parameters.Add("#ID", DbType.Int32).Value = ID
and then you execute:
mycmd.ExecuteScalar()
but there are no parameters in mycmd.
I'm trying to input data from my vb into PostgreSQL
the source is another database on Ms Access
im using this code for connection
Public Function LoadAcces_tblpibconr() As DataTable 'ganti ini sesuai nama table
Dim Table As DataTable = New DataTable()
Command.Connection = conn.OpenConnection()
Command.CommandText = "select * from tblpibconr"
Command.CommandType = CommandType.Text
ReadRows = Command.ExecuteReader()
Table.Load(ReadRows)
ReadRows.Close()
conn.CloseConexion()
Return Table
End Function
'=====================================TABLE POSTGRESQL========================='
Public Function LoadNpgsql_tblpibconr() As DataTable
Dim Table As DataTable = New DataTable()
Cmd.Connection = connNpgsql.OpenConnection()
Cmd.CommandText = "select * from tblpibconr"
Cmd.CommandType = CommandType.Text
ReadRows1 = Cmd.ExecuteReader()
Table.Load(ReadRows1)
ReadRows1.Close()
connNpgsql.CloseConexion()
Return Table
End Function
I'm using this function for filtering the data
I'll compare the data first and take the data without a match and stored it into postgresql
Public Function CekData_tblpibconr(ByVal car As String, ByVal reskd As String, ByVal contno As String) As Boolean
Dim Table As DataTable = New DataTable()
Cmd.Connection = connNpgsql.OpenConnection()
If Cmd.Parameters.Count > 0 Then
Cmd.Parameters.Clear()
End If
Cmd.Parameters.AddWithValue("#car", car)
Cmd.Parameters.AddWithValue("#reskd", reskd)
Cmd.Parameters.AddWithValue("#contno", contno)
Cmd.CommandText = <sql>select * from tblpibconr where car=#car and reskd=#reskd and contno=#contno</sql>.Value
Cmd.CommandType = CommandType.Text
ReadRows1 = Cmd.ExecuteReader() 'ERROR System.InvalidOperationException: 'Parameter '#car' must have its value set'
Table.Load(ReadRows1)
ReadRows1.Close()
If Table.Rows.Count > 0 Then
Return False
Else
Return True
End If
Cmd.Parameters.Clear()
connNpgsql.CloseConexion()
End Function
Sub bandingkan_data_tblpibconr()
For i = 0 To DGV1.Rows.Count - 1
Dim validasi = query.CekData_tblpibconr(DGV1.Rows(i).Cells(0).Value, DGV1.Rows(i).Cells(1).Value, DGV1.Rows(i).Cells(2).Value) 'cek data dari access ke postgresql
If validasi = True Then 'jika data di access tidaj ada
'inser data
Dim a As String
If IsDBNull(DGV1.Rows(i).Cells(4).Value.ToString()) Then
a = "0"
Else
a = DGV1.Rows(i).Cells(4).Value.ToString()
End If
DGV1.Rows(i).DefaultCellStyle.BackColor = Color.MistyRose
Dim Insertdata = query.insertNpgsql_tblpibconr(DGV1.Rows(i).Cells(0).Value.ToString(), DGV1.Rows(i).Cells(1).Value.ToString(), DGV1.Rows(i).Cells(2).Value.ToString() _
, DGV1.Rows(i).Cells(3).Value.ToString(), a)
If Insertdata = True Then
' MsgBox("Masuk")
Else
MsgBox("Data Gagal DIMASUKAN")
End If
End If
Next i
LoadNpgsql_tblpibconr()
MsgBox("Selesai")
End Sub
Public Function insertNpgsql_tblpibconr(ByVal car As String, ByVal reskd As String, ByVal contno As String, ByVal contukur As String, ByVal conttipe As String) As Boolean
Cmd.Connection = connNpgsql.OpenConnection()
If Cmd.Parameters.Count = 0 Then
Cmd.Parameters.Clear()
End If
Try
Cmd.CommandText = "insert into tblpibconr(car,reskd,contno,contukur,conttipe) values(#car,#reskd,#contno,#contukur,#conttipe)"
Cmd.CommandType = CommandType.Text
Cmd.Parameters.AddWithValue("#car", car)
Cmd.Parameters.AddWithValue("#reskd", reskd)
Cmd.Parameters.AddWithValue("#contno", contno)
Cmd.Parameters.AddWithValue("#contukur", contukur)
Cmd.Parameters.AddWithValue("#conttipe", conttipe)
Cmd.ExecuteNonQuery()
str = "insert into tblpibconr(car,reskd,contno,contukur,conttipe) values(#car , #reskd , #contno, #contukur, #conttipe)"
Return True
Catch ex As Exception
MsgBox(ex.Message)
Return False
End Try
connNpgsql.CloseConexion()
End Function
this is the error that I get
System.InvalidOperationException: 'Parameter '#car' must have its
value set'
ITS Refer to ReadRows1 = Cmd.ExecuteReader() on function cekdata_tblpibconr and Dim validasi = query.CekData_tblpibconr(DGV1.Rows(i).Cells(0).Value, DGV1.Rows(i).Cells(1).Value, DGV1.Rows(i).Cells(2).Value) on sub bandingkan_data_tblpibconr
but this error appear after the data successfully inserted to my Postgresql
Before running the Function where the error occurred, I have checked if we really have a value for car.
This method demonstrates what I mean by keeping your database objects local. The connection and command are created locally in a Using block. They will be closed and disposed even it there is an error.
You can pass the connection string directly to the constructor of the connection. Likewise, pass the command text and the connection to the constructor of the command. The default CommandType is CommandType.Text so it is not necessary to explicitly set that property.
Open the connection at the last possible moment directly before the command is executed.
Public Function CekData_tblpibconr(ByVal car As String, ByVal reskd As String, ByVal contno As String) As Boolean
If String.IsNullOrEmpty(car) Then
MessageBox.Show("Car has no value")
Return True '??
End If
Dim Table As DataTable = New DataTable()
Using cn As New NpgsqlConnection(ConStr),
cmd As New NpgsqlCommand("select * from tblpibconr where car=#car and reskd=#reskd and contno=#contno;", cn)
cmd.Parameters.Add("#car", NpgsqlDbType.Varchar).Value = car
cmd.Parameters.Add("#reskd", NpgsqlDbType.Varchar).Value = reskd
cmd.Parameters.Add("#contno", NpgsqlDbType.Varchar).Value = contno
cn.Open()
Table.Load(cmd.ExecuteReader)
End Using
If Table.Rows.Count > 0 Then
Return False
Else
Return True
End If
End Function
I'm making a project that is linked to Microsoft SQLServer, used to enter, remove, edit data about customers and orders. The full system works, however I've been advised to use transactions rather than regular SQL statements to add/remove/edit data etc.
The trouble is, I've not used these before and from my research over the last few hours, I can't work out how to even begin them.
Can anybody advise me how to turn the following code into a transaction?
Public Shared Function SaveNewPerson(ByVal firstName As String, lastName As String, ByVal age As Integer, ByVal postcode As String, m_cn As OleDbConnection)
Dim Dc As New OleDbCommand
Dc.Connection = m_cn
m_cn.Open()
Dc.CommandText = "INSERT INTO tblPerson([firstName], [lastName], [age], [postcode]) VALUES('" & firstName & "', '" & lastName & "', '" & age & "', '" & postcode & "')"
Dc.ExecuteNonQuery()
Dim personID As Integer
Dc.CommandText = "SELECT ##IDENTITY"
Dc.CommandType = CommandType.Text
personID = CType(Dc.ExecuteScalar(), Integer)
m_cn.Close()
End Function
I've just been learning TSQL, see if this sort of code will work for you (note that you need to Dim tr (with a different variable name, if you like) and use it in multiple places, but unlike in some languages you don't need to set up objects for the different methods.
Public Shared Function SaveNewIncident(ByVal clientName As String, dateStart As Date, dateEnd As Date, ByVal incidentProblem As String, ByVal timeStart As String, ByVal timeEnd As String,
ByVal incidentSolved As Boolean, ByVal incidentSolution As String, _con As OleDbConnection)
Dim tr As OleDbTransaction = Nothing
Try
Dim Dc As New OleDbCommand
Dc.Connection = _con
tr = _con.BeginTransaction()
Dc.CommandType = CommandType.Text
Dc.CommandText = "INSERT INTO dbo.tblIncidents VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"
Dc.Transaction = tr
Dc.Parameters.Add("#clientName", OleDbType.VarChar).Value = clientName
Dc.Parameters.Add("#dateStart", OleDbType.Date).Value = dateStart
Dc.Parameters.Add("#dateEnd", OleDbType.Date).Value = dateEnd
Dc.Parameters.Add("#incidentProblem", OleDbType.LongVarChar).Value = incidentProblem
Dc.Parameters.Add("#timeStart", OleDbType.VarChar).Value = timeStart
Dc.Parameters.Add("#timeEnd", OleDbType.VarChar).Value = timeEnd
Dc.Parameters.Add("#incidentSolved", OleDbType.Boolean).Value = incidentSolved
Dc.Parameters.Add("#incidentSolution", OleDbType.LongVarChar).Value = incidentSolution
Dim personID As Integer
Dc.CommandText = "SELECT SCOPE_IDENTITY() AS personID"
Dc.CommandType = CommandType.Text
personID = CType(Dc.ExecuteScalar(), Integer)
tr.Commit()
Catch ex As Exception
tr.Rollback()
Throw
End Try
End Function
I am trying to insert row and update row (if row already exists), as following -
Dim con As SQLiteConnection
Dim sql As String
Dim cmd As New SQLiteCommand
Dim da As SQLiteDataAdapter
Dim ds As New DataSet
Dim NumberOfRows As Integer
Public Sub UpdateUserStatistics(ByVal UserId As Integer, ByVal QId As Integer, _
ByVal KeyName As String, ByVal KeyValue As Integer)
con = New SQLiteConnection("Data Source = " + AppDomain.CurrentDomain.BaseDirectory + "/user_statistics.db;Version=3;")
con.Open()
sql = "SELECT * FROM med_user_meta where user_id=" & UserId & " And qid=" & QId
da = New SQLiteDataAdapter(sql, con)
da.Fill(ds, "UserMeta")
NumberOfRows = ds.Tables("UserMeta").Rows.Count
ds.Clear()
If (NumberOfRows = 0) Then
Dim InsertQuery As SQLiteCommand = con.CreateCommand
InsertQuery.CommandText = "INSERT INTO med_user_meta " _
& "(user_id, qid, " _
& KeyName _
& ", timestamp) VALUES(?, ?, ?, datetime('now'))"
InsertQuery.Parameters.AddWithValue("user_id", UserId)
InsertQuery.Parameters.AddWithValue("qid", QId)
InsertQuery.Parameters.AddWithValue(KeyName, KeyValue)
RowInserted = InsertQuery.ExecuteNonQuery()
ElseIf (NumberOfRows = 1) Then
Dim UpdateQuery As SQLiteCommand = con.CreateCommand
UpdateQuery.CommandText = "UPDATE med_user_meta SET " _
& KeyName _
& " = ?, timestamp = datetime('now') Where qid = ?"
'UpdateQuery.Parameters.AddWithValue("user_id", UserId)
UpdateQuery.Parameters.AddWithValue("qid", QId)
UpdateQuery.Parameters.AddWithValue(KeyName, KeyValue)
RowUpdated = UpdateQuery.ExecuteNonQuery()
End If
con.Close()
End Sub
I am using this code in a module and calling UpdateUserStatistics wherever required
My problem is that, insert query works fine, but update query does Not work.
It's been more than 2 hours, but I couldn't find, where am I making mistake?
Also, is there any way to get the final update query into message box after adding parameters, so that I can check if my final update query is correct?
Edit - 1
I forgot to mention, value of RowUpdated is returning 0, i.e. ExecuteNonQuery is Not updating the row.
I have also confirmed that row corresponding to update query Do exists, and the ElseIf (NumberOfRows = 1) Then block is running too, but it's Not updating the row.
Hi I got an InvalidCastException saying that "Specified cast is not valid.". I dont know where is the problem. Does my code has an error?
This is my code:
Private Sub Form5_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\patientinfo.accdb"
Conn.Open()
'====retrieve values in database=============
Dim statement As String = " SELECT patient_name,patient_age,date_confinement,type_sickness, type_fluid, bottle_used, drop_rate FROM tblPatientInfo WHERE 1 ORDER BY ID "
RetrieveInfos(statement)
End Sub
Public Sub RetrieveInfos(ByRef statement As String)
Dim cmd As OleDbCommand = New OleDbCommand
With cmd
.CommandText = statement
.CommandType = CommandType.Text
.Connection = Conn
.ExecuteNonQuery()
'--read records in access database----------------
Dim reader As OleDbDataReader = cmd.ExecuteReader
If reader.Read Then
lblName.Text = reader.GetString(0)
lblAge.Text = reader.GetString(1)
lblDate.Text = reader.GetString(2)
lblSickness.Text = reader.GetString(3)
lblFluid.Text = reader.GetString(4)
lblBottle.Text = reader.GetString(5)
lbldrops.Text = reader.GetString(6)
reader.Close()
End If
End With
End Sub
Any help would be appreciated. Thanks! :3
A very annoying part of VB working with datatypes is that some of them cause it to have a huge flap if they're empty. Best way around is to convert the ready to either an empty value or the default null value for the data type. Try the following:
lblName.Text = If(reader.isdbnull(0),Nothing,reader.GetString(0))
lblAge.Text = If(reader.isdbnull(1), 0, reader.GetInt16(1))
lblDate.Text = If(reader.isdbnull(2), date.minvalue, reader.Getdatetime(2)
lblSickness.Text = If(reader.isdbnull(3), Nothing, reader.GetString(3)
lblFluid.Text = If(reader.isdbnull(4), Nothing, reader.GetString(4))
lblBottle.Text = If(reader.isdbnull(5), Nothing, reader.GetString(5))
lbldrops.Text = If(reader.isdbnull(6), Nothing, reader.GetString(6))
Based on your comment to the question, I would suggest changing
lblAge.Text = reader.GetString(1)
to
lblAge.Text = reader.GetInt32(1).ToString
Also, make sure you use the appropriate Get for each column. For a Date you should use GetDateTime(). Here is a link to the MSDN for OleDbDataReader; the left side will have a list of all the methods that you can use for reference.
Try checking if the value is null:
If TypeOf reader(1) Is DBNull Then
lblAge.Text = reader.GetString(1)
End If
But that will only work if it's a string. If it's not a string, this should work with any data type:
If TypeOf reader(1) Is DBNull Then
lblAge.Text = reader(1).ToString()
End If