This is the Code:
Private Sub btnSearchMaintDate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearchMaintDate.Click
con.Open()
ListView1.Items.Clear()
cmd = New SqlCommand("SELECT * FROM tblMaintenanceRpt WHERE dates BETWEEN '" & date1.Value & "' AND '" & date2.Value & "'", con)
cmd.CommandType = CommandType.Text
Dim dr As SqlDataReader
dr = cmd.ExecuteReader
While dr.Read
Dim lv As New ListViewItem
With lv
.Text = dr(1).ToString
.SubItems.Add(dr(2).ToString)
.SubItems.Add(dr(3).ToString)
.SubItems.Add(dr(4).ToString)
End With
ListView1.Items.Add(lv)
End While
dr.Close()
con.Close()
End Sub
im having an error in the While dr.read it says SqlException was unhandled. The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value. But when I try to remove the single quotation in my query, it doesn't have an error but the result of getting the range of the date doesn't view in the listview.
Try to use parameter instead of appending dates in the string query :
cmd = New SqlCommand("SELECT * FROM tblMaintenanceRpt WHERE dates BETWEEN #date1 AND #date2", con)
cmd.Parameters.AddWithValue("#date1", date1.Value)
cmd.Parameters.AddWithValue("#date2", date2.Value)
Using parameter also make your application less vulnerable to SQL Injection.
If you want to ignore the time part of datetime values, you can use >= and < instead of BETWEEN (maybe time values are why you're not seeing any results). It may be helpful to put date1.Value and date2.Value in a MessageBox to see what they hold.
Related
While i was adding data to access database, i got error:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TB2.Clear()
NameofG.Clear()
NunberofG.Clear()
UnitofG.Clear()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
pro = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Piyawat\Desktop\PPCC\Stock.accdb;"
connstring = pro
myconnection.ConnectionString = connstring
If myconnection.State = ConnectionState.Closed Then
myconnection.Open()
End If
command = "insert into Stock([InvoiceID],[Type],[Item],[Amout],[Unit]) Value ('" & TB2.Text & "','" & CB1.Text & "','" & NameofG.Text & "','" & NunberofG.Text & "','" & UnitofG.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(command, myconnection)
cmd.Parameters.Add(New OleDbParameter("InvoiceID", CType(TB2.Text, String)))
cmd.Parameters.Add(New OleDbParameter("Type", CType(CB1.Text, String)))
cmd.Parameters.Add(New OleDbParameter("Item", CType(NameofG.Text, String)))
cmd.Parameters.Add(New OleDbParameter("Amout", CType(NunberofG.Text, String)))
cmd.Parameters.Add(New OleDbParameter("Unit", CType(UnitofG.Text, String)))
MsgBox("Record Save")
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
TB2.Clear()
CB1.Text.DefaultIfEmpty
NameofG.Clear()
NunberofG.Clear()
UnitofG.Clear()
Catch ex As Exception
MsgBox("Mistake")
End Try
End Sub
How to fix the error? Please help. Thanks
I would AWAYS ensure that after you use the connection, you close it.
however, you can get .net to automatics do this for you.
Also, go into project->settings and add your connection string there - that way you NEVER have to place or have connection strings in code - (bad idea).
Hence, your code should and would look like this:
Dim strSQL As String = "INSERT INTO Stock([InvoiceID],[Type],[Item],[Amout],[Unit]) " &
"VALUES (#TB2, #CB1, #NameofG, #NunberofG, #UnitofG)"
Using cmd As New OleDbCommand(strSQL, New OleDbConnection(My.Settings.Test44))
cmd.Parameters.Add("#TB2", OleDbType.VarWChar).Value = TB2.Text
cmd.Parameters.Add("#CB1", OleDbType.VarWChar).Value = CB1.Text
cmd.Parameters.Add("NameofG", OleDbType.VarWChar).Value = NameofG.Text
cmd.Parameters.Add("#NumberofG", OleDbType.Integer).Value = NunberofG.Text
cmd.Parameters.Add("#UnitofG", OleDbType.Integer).Value = UnitOfG.Text
cmd.Connection.Open()
Try
cmd.ExecuteNonQuery()
MsgBox("Record Save")
Catch ex As Exception
MsgBox("Error = " & ex.Message)
End Try
End Using
note the following:
No messy string concentation.
No messy quotes for strings, non quotes for numbers.
clean easy to read.
use parmaters - safe.
And with a using block, we do NOT have to dispose or close the conneciton - it is automatic for you. So ALWAYS assume it is closed.
note how we don't have a seperate conneciton object - don't need one.
note how the command object is REALLY nice.
The command object has:
a connection object - you don't need to create a new one
command text
a reader!!! - you can use command object - no need to load + create a reader
I moved the database code to a separate method.
Starting with the user interface code, you first want to validate the input. I had to guess at the datatypes because your code made them all look like strings. I hope this is not true.
It seems you got mixed up with Parameters. I am very glad that you tried to used them but they don't appear in your sql string so they are not being used. You don't want to concatenate strings with user input because it risks sql injection.
The # sign preceding the parameter names is just a convention that makes it easy to recognize.
You need to keep database objects local to the method where they are used. That way they can be closed and disposed with Using...End Using blocks as quickly as possible.
Private ConStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Piyawat\Desktop\PPCC\Stock.accdb;" '"Your connection string"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Validate input
Dim ID As Integer
Dim Amt As Decimal
Dim Unt As Integer
Dim message = "Please enter a number for the"
If Not Integer.TryParse(TB2.Text, ID) Then
MessageBox.Show(message & " Invoice ID.")
Return
End If
If Not Decimal.TryParse(NunberofG.Text, Amt) Then
MessageBox.Show(message & " Amount.")
Return
End If
If Not Integer.TryParse(UnitofG.Text, Unt) Then
MessageBox.Show(message & " Unit")
Return
End If
'Call the insert method
Try
InsertInvoice(ID, CB1.Text, NameofG.Text, Amt, )
Catch ex As Exception
MsgBox(ex.Message)
Return
End Try
MessageBox.Show("Record Saved")
TB2.Clear()
CB1.Text.DefaultIfEmpty
NameofG.Clear()
NunberofG.Clear()
UnitofG.Clear()
End Sub
Private Sub InsertInvoice(InvoiceID As Integer, Type As String, Item As String, Amount As Decimal, Unit As Integer)
Dim Command = "insert into Stock([InvoiceID],[Type],[Item],[Amout],[Unit]) Value (#InvoiceID,#Type,#Item,#Amount,#Unit)"
Using myconnection As New OleDbConnection(ConStr),
cmd As New OleDbCommand(Command, myconnection)
With cmd.Parameters
.Add("#InvoiceID", OleDbType.Integer).Value = InvoiceID
.Add("#Type", OleDbType.VarChar).Value = Type
.Add("#Item", OleDbType.VarChar).Value = Item
.Add("#Amout", OleDbType.Decimal).Value = Amount
.Add("#Unit", OleDbType.Integer).Value = Unit
End With
End Using
End Sub
I have a problem on making avoid or detect duplicate data entry in VB.NET using SQL Server, and also pop up message when there is duplicate entry.
This is my add button code:
Dim sql = "INSERT INTO studentAttendence(studentID, date, time, subject, attendence) " &
"VALUES(#studentID, #date, #time, #subject, #attendence)" &
"WHERE NOT EXISTS(SELECT * FROM studentAttendence WHERE studentID = #studentID)"
Using cn As New SqlConnection("My sql Connection string")
Dim commands As SqlCommand = New SqlCommand(sql, cn)
commands.Parameters.Add("#studentID", SqlDbType.NVarChar).Value = TextBox1.Text
commands.Parameters.Add("#date", SqlDbType.NVarChar).Value = DateTimePicker1.Text
commands.Parameters.Add("#time", SqlDbType.NVarChar).Value = DateTimePicker2.Text
commands.Parameters.Add("#subject", SqlDbType.NVarChar).Value = ComboBox1.Text
commands.Parameters.Add("#attendence", SqlDbType.NVarChar).Value = ComboBox2.Text
commands.ExecuteNonQuery()
End Using
Or is there any other methods for making avoid duplicate entries. I just want to avoid same date and subject of a student to add. So I can only add subject on the next date if I already add subject on today's date of studentID.
You can use If Not Exists before the insert. This method only requires a single hit on the database. Add a comman at the end of the first line of the Using block, then delete Dim before commands. This will include commands in the Using block.
Private Function InsertAttendance() As Integer
Dim sql = "If Not Exists (Select 1 From studentAttendence
Where studnetID = #studentID And date = #date And subject = #subject)
INSERT INTO studentAttendence(studentID, date, time, subject, attendence)
VALUES(#studentID, #date, #time, #subject, #attendence);"
Dim NumRowsAffected As Integer
Using cn As New SqlConnection("My sql Connection string"),
commands As SqlCommand = New SqlCommand(sql, cn)
commands.Parameters.Add("#studentID", SqlDbType.NVarChar).Value = TextBox1.Text
commands.Parameters.Add("#date", SqlDbType.NVarChar).Value = DateTimePicker1.Text
commands.Parameters.Add("#time", SqlDbType.NVarChar).Value = DateTimePicker2.Text
commands.Parameters.Add("#subject", SqlDbType.NVarChar).Value = ComboBox1.Text
commands.Parameters.Add("#attendence", SqlDbType.NVarChar).Value = ComboBox2.Text
cn.Open()
NumRowsAffected = commands.ExecuteNonQuery()
End Using
Return NumRowsAffected
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
If InsertAttendance() = 1 Then
MessageBox.Show("Success")
Else
MessageBox.Show("Duplicate Entry")
End If
Catch ex As Exception
MessageBox.Show($"Error Entering Attendance {ex.Message}")
End Try
End Sub
Be sure to check the datatypes of your parameters with the database.
You should create a function that queries your data table to return the row count where the Date, Subject, and StudentId match what you're wanting to insert. If the returned result is greater than 0 then display the message.
Here is a function that returns -1 if something went wrong or the row count:
Private Function GetRowCount(ByVal studentIdParameter As String, ByVal dateParameter As DateTime, ByVal subjectParameter As String) As Integer
'Declare the object to return
Dim count As Integer = -1
'Declare the connection object
Dim con As OleDbConnection
'Wrap code in Try/Catch
Try
'Set the connection object to a new instance
'TODO: Change "My Connection String Here" with a valid connection string
con = New OleDbConnection("My Connection String Here")
'Create a new instance of the command object
'TODO: Change [ID] to a valid column
Using cmd As OleDbCommand = New OleDbCommand("SELECT Count([ID]) FROM [MyTable] WHERE studentID=#studentId, AND date=#date AND subject=#subject", con)
'Parameterize the query
cmd.Parameters.Add("#studentId", OleDbType.NVarChar).Value = studentIdParameter
cmd.Parameters.Add("#date", OleDbType.DBDate).Value = dateParameter.Date
cmd.Parameters.Add("#subject", OleDbType.NVarChar).Value = subjectParameter
'Open the connection
con.Open()
'Use ExecuteScalar to return a single value
count = Convert.ToInt32(cmd.ExecuteScalar())
'Close the connection
con.Close()
End Using
Catch ex As Exception
'Display the error
Console.WriteLine(ex.Message)
Finally
'Check if the connection object was initialized
If con IsNot Nothing Then
If con.State = ConnectionState.Open Then
'Close the connection if it was left open(exception thrown)
con.Close()
End If
'Dispose of the connection object
con.Dispose()
End If
End Try
'Return the row count
Return count
End Function
To implement it, you'd do something like:
Dim rowCount = GetRowCount(TextBox1.Text, DateTimePicker1.Value, ComboBox1.Text)
If (rowCount = -1) Then
MessageBox.Show("Something went wrong checking for duplicates")
ElseIf (rowCount = 0) Then
' Insert record
Else
MessageBox.Show("A record already exists with this studentId, date, and subject.")
End If
when iam trying to write this select in vb.net and sqlserver database:
da = New SqlDataAdapter("select * from UserComeView where ( ComeUserFullName=" & cmb_user.SelectedValue & " ) and ( ComeDate between '" & Date1.Value & "' and '" & Date2.Value & "')", sql.sqlcon)
comes this error:
Conversion failed when converting date and/or time from character
string.
I will assume that ComeDate is some type of Date field. I altered your Select command to include parameters. Defining the datatype in the .Add method should clear up your conversion problem. I had to guess at the datatype. Check the datatype in your database. Then pass the command, which includes the connection, to the constructor of the DataAdapter.
Private Sub OpCode()
Dim dt As New DataTable
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand("Select * From UserComeView Where ComeUserFullName = #FullName And ComeDate Between #Date1 And #Date2;", cn)
cmd.Parameters.Add("#FullName", SqlDbType.NVarChar, 200).Value = cmb_user.SelectedValue
cmd.Parameters.Add("#Date1", SqlDbType.Date).Value = Date1.Value
cmd.Parameters.Add("#Date2", SqlDbType.Date).Value = Date2.Value
Using da As New SqlDataAdapter(cmd)
da.Fill(dt)
End Using
End Using
DataGridView1.DataSource = dt
End Sub
I'm writing a vb.net programming that could retrieve all relevant data from SQL server DB based on the date range like eg. 3 October 2016 to 7 October 2016. I had two DateTime pickers to act as "Date From" and "Date To" respectively and so far the below code was able to retrieve the data based on what I had set on both of my DateTime picker.
Dim dFrom As DateTime = dtDateFrom.Value
Dim dTo As DateTime = dtDateTo.Value.AddDays(1)
Dim queryIncident As String
dgvGen.Columns.Clear()
cn.Open()
queryIncident = "SELECT * FROM tblIncidentTrackingMod WHERE TimeStamp BETWEEN '" & Format(dFrom, "dd-MM-yyyy") & "' AND '" & Format(dTo, "dd-MM-yyyy") & "'"
da = New SqlDataAdapter(queryIncident, cn)
ds = New DataSet
da.Fill(ds, "dsGenerate")
dgvGen.DataSource = ds.Tables("dsGenerate")
dgvGen.DataSource = ds.Tables(0)
cn.Close()
Now here's the issue. When I attempted to select a date range based on particular weeks that will cross over to a new month like eg. "28 Nov 2016 to 2 Dec 2016", the program could not retrieve any of the related data based on that date range. Clearly I have data containing these dates in SQL server DB but it's not appearing. I had looked up for solutions but couldn't any, so I was hoping to find a solution here. Thanks!
Use parameters in your sql command. No need to open the connection. SqlDataAdapter will automatically do this when you call its Fill method.
Dim cmd As SqlCommand = cn.CreateCommand()
cmd.CommandText = "SELECT * FROM tblIncidentTrackingMod WHERE TimeStamp BETWEEN #from AND #to"
cmd.Parameters.AddWithValue("#from", dFrom)
cmd.Parameters.AddWithValue("#to", dTo)
da = New SqlDataAdapter(cmd)
ds = New DataSet
da.Fill(ds, "dsGenerate")
dgvGen.DataSource = ds.Tables(0)
Dim MLD As New Globalization.GregorianCalendar
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
T1.Value = DateAndTime.Now
Catch ex As Exception
End Try
End Sub
Private Sub T1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles T1.ValueChanged
ChangeDD1()
End Sub
Private Sub ChangeDD1()
Try
Dim ADay, AMonth As String
ADay = MLD.GetDayOfMonth(T1.Value)
AMonth = MLD.GetMonth(T1.Value)
If ADay.Length = 1 Then
ADay = "0" & ADay
End If
If AMonth.Length = 1 Then
AMonth = "0" & AMonth
End If
TD1.Text = ADay & AMonth & MLD.GetYear(T1.Value)
Catch ex As Exception
End Try
End Sub
and Save TD1.Text as string in your database
I have difficulty with the following code. I think it lies in my sql statement.
I get the error :
Operand type clash: date is incompatible with int
Dim strSql5 As String = "SELECT * FROM dbo.ontledings where plaasblok = '" & plaasblokparsversoeke & "' and analisedatum = " & laastedatum.Date
MsgBox(strSql5)
Dim dtb5 As New DataTable
dtb5.Clear()
Using cnn As New SqlConnection("Data Source=GIDEON-E-LAPTOP\SQLEXPRESS2014;Initial Catalog=SkeduleringDatabasis;Integrated Security=True")
cnn.Open()
Using dad5 As New SqlDataAdapter(strSql5, cnn)
dad5.Fill(dtb5)
End Using
cnn.Close()
End Using
Dim laasteontleding As Decimal = dtb5.Rows(0)("suiker")
I get the laastedatum from the following code :
Dim laastedatum As Date = dtb4.Rows(0)("last")
Any help would be much appreciated.
Regards
Do not use SELECT *, use SELECT field list. Then use Field(Of T) to get the date information strongly typed. Always used Option Strict On.
Example reading order data from Microsoft NorthWind database orders table, note the field retrieval.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim EmployeeId As Integer = 2
Dim dt As New DataTable
Using cn As New SqlClient.SqlConnection With {.ConnectionString = My.Settings.ConnectionString}
Using cmd As New SqlClient.SqlCommand With {.Connection = cn}
cmd.CommandText =
<SQL>
SELECT [OrderID]
,[CustomerID]
,[EmployeeID]
,[OrderDate]
,[ShipCountry]
FROM [NORTHWND.MDF].[dbo].[Orders]
WHERE [EmployeeID] = #EmployeeID
ORDER BY CustomerId
</SQL>.Value
cmd.Parameters.AddWithValue("#EmployeeID", EmployeeId)
cn.Open()
dt.Load(cmd.ExecuteReader)
For Each row As DataRow In dt.Rows
Console.WriteLine("id: {1} date: {0}",
row.Field(Of Date)("OrderDate").ToShortDateString,
row.Field(Of String)("CustomerId"))
Next
End Using
End Using
End Sub
End Class
Get first date
Dim rowOneOrderDate As Date = dt.Rows(0).Field(Of Date)("ORderDate")