Datetime VB net to SQL table - sql-server

I have this:
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim con As New SqlConnection
Dim myCommand As New SqlCommand
Try
Dim a As String
con.ConnectionString = "Data Source=SVNAV;Initial Catalog=NAV_Vermorel_Live;User ID=sa;Password=1234"
con.Open()
Dim laser As String
Dim debit As String
Dim indoire As String
Dim uzinaj As String
Dim dlaser As Nullable(Of DateTime) = DateTime.Now
Dim ddebit As Nullable(Of DateTime) = DateTime.Now
Dim dindoire As Nullable(Of DateTime) = DateTime.Now
Dim duzinaj As Nullable(Of DateTime) = DateTime.Now
If NewCheckBox1.Checked = True Then
laser = "Finished"
Else
laser = "In Progress"
dlaser = Nothing
End If
If NewCheckBox2.Checked = True Then
debit = "Finished"
Else
debit = "In Progress"
ddebit = Nothing
End If
If NewCheckBox3.Checked = True Then
indoire = "Finished"
Else
indoire = "In Progress"
dindoire = Nothing
End If
If NewCheckBox4.Checked = True Then
uzinaj = "Finished"
Else
uzinaj = "In Progress"
duzinaj = Nothing
End If
a = "INSERT INTO [dbo].[SC Vermorel SRL$PregatirePROD]
(
[FPO]
,[Articol]
,[Descriere]
,[Cantitate]
,[LASER]
,[DEBITARE]
,[INDOIRE]
,[UZINAJ]
,[EndDateLASER]
,[EndDateDEBIT]
,[EndDateINDOIRE]
,[EndDateUZINAJ])
VALUES
(#FPO,
#Articol
,#Descriere
,#Cantitate
,#LASER
,#DEBITARE
,#INDOIRE
,#UZINAJ
,#EndDateLASER
,#EndDateDEBIT
,#EndDateINDOIRE
,#EndDateUZINAJ)"
myCommand = New SqlCommand(a, con)
myCommand.Parameters.AddWithValue("#FPO", txtFpo.Text)
myCommand.Parameters.AddWithValue("#Articol", txtItem.Text)
myCommand.Parameters.AddWithValue("#Descriere", txtDesc.Text)
myCommand.Parameters.AddWithValue("#Cantitate", txtQty.Text)
myCommand.Parameters.AddWithValue("#LASER", laser)
myCommand.Parameters.AddWithValue("#DEBITARE", debit)
myCommand.Parameters.AddWithValue("#INDOIRE", indoire)
myCommand.Parameters.AddWithValue("#UZINAJ", uzinaj)
myCommand.Parameters.AddWithValue("#EndDateLaser", dlaser)
myCommand.Parameters.AddWithValue("#EndDateDEBIT", ddebit)
myCommand.Parameters.AddWithValue("#EndDateINDOIRE", dindoire)
myCommand.Parameters.AddWithValue("#EndDateUZINAJ", duzinaj)
myCommand.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Eroare ..." & ex.Message, "Inserare campuri")
Finally
con.Close()
End Try
Me.SC_Vermorel_SRL_PregatirePRODTableAdapter.Fill(Me.NAV_Vermorel_LiveDataSet._SC_Vermorel_SRL_PregatirePROD)
End Sub
The table design from, prtscreen from SSM:
Im trying to add the DateTime.Now value of dlaser into an SQL field. I get SQL type overflow, dates must be between etc etc.
The format of date witch SMS displays is: 2016-09-30 14:58:46.343. SQL Server 2005.
How can i be sure that vb net application outputs datetime in same format?

In the Else part you leave VB variable dlaser uninitialized, which means it has value 0001-01-01 00:00:00. But that variable is always used for parameter #EndDateLaser to set column [EndDateLASER].
Column [EndDateLASER] has SQL type datetime, but datetime does not allow 0001-01-01, the minimum value allowed is 1753-01-01.
Apart from that, I wonder why you sometimes add a #dlaser SqlParameter (with value DBNull). For the query as shown that parameter is irrelevant because it does not use #dlaser anywhere. And also, why add it only in one situation, while your query is fixed.

Please Use This
DateTime.Now.ToString("dd-MMM-yyyy")
in Place of
DateTime.Now
and dlaser is take string
dim dlaser as string

Related

How to pass dynamic parameter from SQL query to the SqlCommand after user input on the SQL query

all. I am facing an issue on how to pass the dynamic parameter value from SQL query, that will be entered by the user into the textbox, to the SQL command to search on the parameter value on the datagridview datatable.
For my project, a textbox will be provided for the user to key in the SQL query dynamically to search on the database data. If the user keys in SQL query like
select *
from table
where a = #a
The user can search on #a parameter value; if the user keys in SQL query like
select *
from table
where a = #a and b = #b
The user can search the #a and #b parameter values by using textbox, which means that the parameter number that had been entered by the user needs to be calculated, retrieved, passed to the SQL command and allow the user to filter on the parameter by using textbox provided.
However, currently, due to the #a parameter and #b parameter will be key in by the user dynamically during runtime, so I faced difficulty to declare/define the parameter name on the cmd.Parameters.AddWithValue() statement.
Can anyone help me to solve my problem by providing me some solutions on codes? I had been stuck on this issue for a few days already. Thank you for all the help!
The code I had tried:
Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click
Sql = TextBox4.Text
Try
'open database
Dim con As New SqlConnection(dbstring)
con.Open()
Dim cmd As New SqlCommand(Sql, con)
If param IsNot Nothing Then
For Each para As SqlParameter In param
'cmd.Parameters.Add(para)
For m As Integer = 0 To param.Count - 1
cmd.Parameters.Add(New SqlParameter With {.ParameterName = para.ParameterName(m),
.Value = para.Value(m),
.SqlDbType = SqlDbType.NVarChar,
.Size = 99})
Next
cmd.ExecuteNonQuery()
Next
End If
Using sda = New SqlDataAdapter()
sda.SelectCommand = cmd
cmd.CommandText = Sql
Sql = cmd.ExecuteScalar()
Using ds As DataSet = New DataSet()
sda.Fill(ds)
con.Close()
DataGridView1.DataSource = ds.Tables(0)
End Using
End Using
con.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Screenshot of Window App Formhad been provided as a reference.
To avoid SQL Injection, im usally doing like this:
Dim text1 As String = "text1"
Dim objComm As SqlCommand = New SqlCommand
objComm.Parameters.AddWithValue("#text1", text1)
objComm.CommandText = "SELECT * FROM TABLE WHERE Text1 = #text1"
I am not sure why you would want the user to write Select statements. I assume this query is on a single table where you know the field names, types and field sizes where applicable. I made up the these items. You will have to check your database to get the correct information.
I used Optional parameters in case you have other datatypes like Booleans or numbers where you can supply the defaults. To pass no value for the parameter just leave a blank but insert the appropriate commans.
Private Function GetSearchResults(Optional FirstName As String = "", Optional LastName As String = "") As DataTable
Dim dt As New DataTable
Using con As New SqlConnection(dbstring),
cmd As New SqlCommand()
Dim sb As New StringBuilder
sb.Append("Select * From SomeTable Where 1 = 1")
If FirstName <> "" Then
cmd.Parameters.Add("#a", SqlDbType.NVarChar, 100).Value = FirstName
sb.Append(" And FirstName = #a")
End If
If LastName <> "" Then
cmd.Parameters.Add("#b", SqlDbType.NVarChar, 100).Value = LastName
sb.Append(" And LastName = #b ")
End If
sb.Append(";")
Debug.Print(sb.ToString)
cmd.CommandText = sb.ToString
cmd.Connection = con
con.Open()
dt.Load(cmd.ExecuteReader)
End Using
Return dt
End Function
Alternative useage:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim dt = GetSearchResults(TextBox1.Text, TextBox2.Text)
DataGridView1.DataSource = dt
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim dt = GetSearchResults(, TextBox2.Text)
DataGridView1.DataSource = dt
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim dt = GetSearchResults(TextBox1.Text, )
DataGridView1.DataSource = dt
End Sub

How to detect it was duplicate entry on VB.NET?

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

vb.net SQL Server DB retrieving all results based on Date Range using 2 DateTime Picker

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

Operand type clash: date is incompatible with int

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")

problems on getting the date range in listview

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.

Resources