Select depends on date VB.NET and SQL Server - sql-server

I want to count the number of PPM orders this month and every month, And this is my code but when I run I get an error
Incorrect syntax near '#'
I need to know generally how to select depending on date, I hate working with date, help me please. Thanks
Dim dtp0 As New DateTimePicker
Dim dtp1 = dtp0.Value
Dim count_m As Integer
Dim cmd1 As New SqlCommand("SELECT count ([id]) FROM [machines] where ppm1 = #" & dtp1.Day & "/" & dtp1.Month & "/" & dtp1.Year & " # and [takhen] is NULL and [irga] is NULL", connsql)
Dim da1 As New SqlDataAdapter(cmd1)
Dim dt1 As New DataTable
da1.Fill(dt1)
If dt1.Rows.Count > 0 Then
connsql.Open()
count_m = Convert.ToInt32(cmd1.ExecuteScalar())
connsql.Close()
Label68.Text = count_m.ToString
End If

I'll provide advice on how to properly use string concatenation to insert a date into SQL code, given that that is the specific question you're asking, but you should absolutely NOT do that. You should ALWAYS use parameters to insert ANY values into SQL code. Here is my own writeup on that.
As for this specific issue, you need to use the correct date format and there's a much easier way to do that than inserting day, month and year separately, e.g.
Dim sql = $"SELECT * FROM MyTable WHERE DateColumn = #{myDTP.Value:M/dd/yyyy}#"
That is using string interpolation, which is the most correct option in the last couple of VB versions. If you're using an older version then you can use String.Format:
Dim sql = String.Format("SELECT * FROM MyTable WHERE DateColumn = #{0:M/dd/yyyy}#", myDTP.Value)
If you wanted to do it wrong then you could use concatenation operators:
Dim sql = "SELECT * FROM MyTable WHERE DateColumn = #" & myDTP.Value.ToString("M/dd/yyyy") & "#"

Simply using parameters to pass a DateTime value will avoid problems with the date string literal and provide many other benefits too.
Code example:
Dim dtp0 As New DateTimePicker
Dim dtp1 = dtp0.Value
Dim count_m As Integer
Dim cmd1 As New SqlCommand("SELECT count ([id]) FROM [machines] where ppm1 = #ppm1 and [takhen] is NULL and [irga] is NULL;", connsql)
Dim param1 As SqlParameter = cmd1.Parameters.Add("#ppm1", SqlDbType.Date)
param1.Value = New DateTime(dtp1.Year, dtp1.Month, dtp1.Day)
Dim da1 As New SqlDataAdapter(cmd1)
Dim dt1 As New DataTable
da1.Fill(dt1)
If dt1.Rows.Count > 0 Then
connsql.Open()
count_m = Convert.ToInt32(cmd1.ExecuteScalar())
connsql.Close()
Label68.Text = count_m.ToString
End If

Related

Reading data from LINQ query

I am new to LINQ query and writing a SSIS script task to read data from two data tables.
I have created the following query, where I want to output to be sent by an email as a table. The body of the email will be the output.
I am able to see the result. But dont know how to use this data (New to linq).
Here is my code:-
Dim Filename As String
Dim Filepath As String
Dim i As Integer
Filename = "TM_xxx_DAILY_*" + Dts.Variables("User::VLoaddt").Value.ToString + "_*.txt"
Filepath = Dts.Variables("User::vSrcFolder").Value.ToString
Dim di As DirectoryInfo = New DirectoryInfo(Filepath)
Dim fi As FileInfo() = di.GetFiles(Filename)
Dim DestTab As DataTable
DestTab = New DataTable("DestinationTable")
Dim column As DataColumn = New DataColumn("Dest")
column.DataType = System.Type.GetType("System.String")
DestTab.Columns.Add(column)
DestTab.Rows.Add("TM_xxx_ONLINE")
DestTab.Rows.Add("TM_xxx_RETAIL")
DestTab.Rows.Add("TM_xxx_TELESALES")
DestTab.Rows.Add("TM_xxx_DAILY_DEVICE")
Dim SrcTab As DataTable
SrcTab = New DataTable("SourceTable")
Dim column1 As DataColumn = New DataColumn("Source")
column1.DataType = System.Type.GetType("System.String")
Dim column2 As DataColumn = New DataColumn("FileExists")
column2.DataType = System.Type.GetType("System.String")
SrcTab.Columns.Add(column1)
SrcTab.Columns.Add(column2)
For i = 0 To fi.Length - 1
SrcTab.Rows.Add(Left(fi.GetValue(i).ToString, Len(fi.GetValue(i).ToString) - 20), "Exists")
Next
Dim query =
From a In DestTab
Group Join b In SrcTab
On a.Field(Of String)("dest") Equals b.Field(Of String)("Source")
Into Group
Let b = Group.FirstOrDefault
Select dest = a.Field(Of String)("dest"), FileExists = If(b Is Nothing, "Missing", b.Field(Of String)("FileExists"))
The biggest challenge and I am not able to understand how to use the variable "query" in "Dim query". While examples in the net and able to use it as a datarow, copytodatatable and other. I can only see tostring,equals and things like that.
My objective is to read files in a folder join it with "Destinationtable" and find the missing ones.
The codes written below are the one right after the select statement
Error Screenshots
I think you should use
For each line in query.ToList()
Dim drRow as DataRow
drRow = MT.NewRow
drRow("Filename") = line.Item(0)
MT.Rows.Add(drRow)
Next
Instead of
For each line in query
MT.Rows.Add(query)
Next

Pull value from SQL Server in VB.NET

I am attempting to pull values from an SQL Server table from VB.NET.
On VB Form 1, the number from NoTable, Row 1, is pulled successfully, and Label1 is updated with the value.
Dim command As SqlCommand
Dim query As String = "SELECT Number FROM NoTable"
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
If datareader.Read() Then
Label1.Text = datareader.GetValue(0)
End If
datareader.Close()
On VB Form 2 I am attempting to pull the value from the second row, using:
Dim query As String = "SELECT Number FROM NoTable"
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
If datareader.Read() Then
Label1.Text = datareader.GetValue(1)
End If
datareader.Close()
However, this does not work, and the label is not updated with the value from the second row.
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll
Additional information: Index was outside the bounds of the array."
How would I go about fixing this, so that on Form 2, the value from Row 2 is pulled, and so forth?
Thank you.
Firstly, you only get one column back from the reader, but you are indexing the columns with that 0 or 1. So you should always pass 0 to GetValue.
To index the row instead, try this. Assign a form number to each form (first line in my example) and use that to determine which record to assign to the Label. There is probably a more efficient way to do this (not returning all the records before it) but this solution should fit in your environment.
' in form # 1
Dim formNumber = 1
Dim command As SqlCommand
Dim query As String = "SELECT Number FROM NoTable"
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
Dim index = 0
While index < formNumber
If datareader.Read() AndAlso index = formNumber Then
Label1.Text = datareader.GetValue(0)
End If
index += 1
End While
datareader.Close()
See https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getvalue(v=vs.110).aspx
And another similar question in c# Access a specific row in DataReader
Another way is to just return the row you need in the first place, without iterating over the records on the client side. Assuming there is another column with an index which is in the same order as the row you want to return, called "ID"
' in form # 1
Dim formNumber = 1
Dim command As SqlCommand
Dim query As String =
"SELECT Number FROM " & _
" (SELECT Number, Row_Number() OVER (ORDER BY ID) AS RowNumber " & _
" FROM NoTable) AS Results " & _
" WHERE Results.RowNumber = " & formNumber.ToString()
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
Label1.Text = datareader.GetValue(0)
datareader.Close()
See https://msdn.microsoft.com/en-us/library/ms186734.aspx
GetValue(1) does not exist, as this would refer to a second column in the select statement. You are only asking for [Number] which would be datareader.GetValue(0)

How to insert date and retrieve records based on that entered date

I am a PHP-MySql Guy & new to the vb.net & SQL Server CE.
how to handle records based on dates ?
Consider any table(tbl_demo) with with some columns having 1 column to store today's date.
For example (table structure)- Id Name today
-- ----- -----
int nvarchar datetime
If i have following data in a table -
Id Name today
-- ----- -----
1 vikram 11/08/2013 11:16:57 PM
then how do i retrieve this record by providing only 11/08/2013 to the query ?
PS-
I have facing following problem while executing the query (here is the code snippet) -
Dim Ddate As Date
Ddate = MonthCalendar1.SelectionRange.Start.ToString
SQLquery = "SELECT id,today FROM tbl_demo WHERE today = '" & Ddate & "'"
ERROR :The data type is not valid for the boolean operation.[Data type (if known) = datetime,Data type (if known) = nvarchar]
Though it is not best to have functions in the fields in the where clause (performance wise) this will do the job.
"SELECT id,today FROM tbl_demo WHERE CONVERT(DATETIME,CONVERT(VARCHAR,today,120)) = CONVERT(DATETIME,CONVERT(VARCHAR,'" & Ddate.ToString() & "',120))"
An alternative would be providing the Date directly to ISO format:
"SELECT id,today FROM tbl_demo WHERE CONVERT(DATETIME,CONVERT(VARCHAR,today,120)) = CONVERT(DATETIME,CONVERT(VARCHAR,'" & Ddate.ToString("yyyyMMdd") & "',120))"
I am not sure if it is yyyyMMdd or yyMMdd for SQL CE, so better try both.
According to this MSDN article it should be "yyMMdd" but it could be a typo...
While experimenting...I got this working as follows (please correct me if i wrong)
Dim Ddate As Date
Dim d, m, y
Ddate = MonthCalendar1.SelectionRange.Start.ToString
d = Ddate.ToString("dd")
m = Ddate.ToString("MM")
y = Ddate.ToString("yyyy")
And the Query is :
SQLquery = "SELECT billId,c_id,amount FROM tbl_outward WHERE (DATEPART(dd, ddate) = '" & d & "' AND DATEPART(mm, ddate) = '" & m & "' AND DATEPART(yyyy, ddate) = '" & y & "')"
Here's a complete example using a Data Reader. This is appropriate if you are going to process one row at a time. If you need to hold all the rows in memory or perform further operations you may want to use ExecuteDataSet to get the values.
This example prints the row values to the command line.
Dim recordDate as DateTime = new DateTime(2013,8,11)
Using connection As SqlCeConnection = New SqlCeConnection("Data Source=Database.sdf;Persist Security Info=False;")
connection.Open()
Using command As SqlCeCommand = connection.CreateCommand()
command.CommandText = "Select id, name, today from demo where today = #date"
Dim dateParameter As SqlCeParameter
dateParameter = New SqlCeParameter("#date", DbType.DateTime)
dateParameter.Value = recordDate
command.Parameters.Add(dateParameter)
Using reader As SqlCeDataReader = command.ExecuteReader()
Do While reader.Read()
Dim id As Integer = reader.GetInt32(0)
Dim name As String = reader.GetString(1)
Dim today As DateTime = reader.GetDateTime(2)
Console.WriteLine("{0,-4} {1,-10} {2,-10}", id, name, today)
Loop
End Using
End Using
End Using
A few important things to note:
The Using statements automatically clear up unused resources when you are finished with them
The sql statement used is parameterised, which allows you to pass in a strongly typed value rather than a string.
The first argument to Console.WriteLine is a string format. {0, -4} is a placeholder that will be filled by the next argument. -4 say that the value should be displayed left aligned in a column 4 characters wide. For more information, see the String.Format method documentation on MSDN.

DataTimePicker for ListView

Is there a way to use DateTimePicker as your searching device for ListView?
I don't know how to use DateTimePicker as my search engine...
HERE IS THE CODES FOR MY SEARCH:
Dim conn As SqlConnection
Dim cmd As SqlCommand
Dim da As SqlDataAdapter
Dim ds As DataSet
Dim itemcoll(100) As String
Me.ListView1.View = View.Details
Me.ListView1.GridLines = True
ListView1.Items.Clear()
conn = New SqlConnection("Data Source=#####;Initial Catalog=#####;Persist Security Info=True;User ID=#####;Password=#####")
Dim strQ As String = String.Empty
strQ = "SELECT ControlNo,EmpNo,CheckOutDate,CheckOutTime,TaxiNo,PlateNo,Model,Make FROM dbo.ChkInOut WHERE ControlNo ='" + txtsearch.Text + "'"
cmd = New SqlCommand(strQ, conn)
da = New SqlDataAdapter(cmd)
ds = New DataSet
da.Fill(ds, "Table")
Dim i As Integer = 0
Dim j As Integer = 0
For i = 0 To ds.Tables(0).Rows.Count - 1
For j = 0 To ds.Tables(0).Columns.Count - 1
itemcoll(j) = ds.Tables(0).Rows(i)(j).ToString()
Next
Dim lvi As New ListViewItem(itemcoll)
Me.ListView1.Items.Add(lvi)
Next
There are few problems with your code as is, so let's take them one at a time
SqlCommand inherits from DbCommand, which implements the IDisposable interface.
The primary use of this interface is to release unmanaged resources.
The best way do that is with the Using keyword. For a code example of that, take a look at the sample code at the bottom of this page.
Same goes for SqlConnection, wrap it in a Using statement.
Don't concatenate strings together to make SQL queries, this opens your application up to SQL Injection attacks. There are examples of how to create parameterized queries here and here (unfortunately I didn't see a good example on MSDN).
In your case, the query will look like this:
strQ = "SELECT ControlNo, ..<rest of columns>.. ,Model,Make " & _
"FROM dbo.ChkInOut " & _
"WHERE ControlNo = #controlNo"
cmd = New SqlCommand(strQ, conn)
cmd.Parameters.AddWidthValue("#controlNo", txtsearch.Text);
... rest of code here ...
To query by a user specified date, you need to first get the date from the DateTimePicker.Value property. Then construct a query (like in the example above) and pass a parameter with the selected date. You may find this question abou SQL Server dates helpful.

Access VBA Comparing Table Values to Constant And Updating It

Ok so I'm trying to writing VBA code to automate as much as possible. What I need it to do is read from a field in a table and if it meets the conditions than it copy that to a new table. It's for rotation purposes. If CurrentDate equals NextDateOut than whatever value of that item I want to go to a certain table but also want to update values in the current table. NextDateOut will be the new LastDateOut value in the table and NextDateIn will be 10 days from NextDateIn and NextDateOut will be 10 days from then. I can write the math logic of this it's just the comparing my values from my table to my constant which right now is CurrentDate and updating the values and writing the values to a certain table when the conditions meet.
Here's the code so far and there's a lot of mistakes trying to figure it out as well.
Option Explicit
Sub Run()
'Declarations for grabbing data from the database for the VBA
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
'Open connection to current Access database
Set db = CurrentDb()
'Declarations for variables to deal with dates
Dim CurrentDate As Date
Dim NextDateOut As Date
Dim NextDateIn As Date
Dim LastDateOut As Date
Dim LastDateIn As Date
'Setting a consistant value, technically not a constant value since there's no "const"
CurrentDate = Date
'Will take this out eventually
MsgBox (CurrentDate)
strSQL = "SELECT Next Date Out FROM Tapes Where Next Date Out = CurrentDate"
Set rst = db.OpenRecordset(strSQL, dbOpenDynaset)
With rst
If .RecorCount > 0 Then
.MoveFirst
.Edit
!Next Date Out = (CurrentDate+20)
.Update
End If
End With
End Sub
Thanks in ADVANCE!!! I'm making progress but hitting walls on the way. THANKS AGAIN!!!
I think you can solve this directly with queries.
Let's split this problem into steps:
If NextDateOut (a field in your table) equals currentDate (a variable in your code), then:
You need to move all records for which the condition is true to a new table
For the records that remain in the table, you need to update LastDateOut to currentDate, nextDateIn to currentDate + 10 and nextDateOut to currentDate + 20
If this is correct, you can try this:
dim strSQL as String
dim currentDate as Date
...
' Step 1: Copy the records to a new table '
strSQL = "insert into otherTable " & _
"select * from tapes " & _
"where [nextDateOut]=" & CDbl(currentDate)
doCmd.runSQL strSQL
' Step 2: Delete the records just copied '
strSQL = "delete from tapes where [nextDateOut]=" & CDbl(currentDate)
doCmd.runSQL strSQL
' Step 3: Update the dates in ALL the records remaining the "tapes" table '
strSQL = "update tapes " & _
"set [lastDateOut]=" & CDbl(currentDate) & ", " & _
"set [nextDateIn]=" & CDbl(currentDate + 10) & ", " & _
"set [nextDateOut]=" & CDbl(currentDate + 20)
doCmd.runSQL strSQL
...
Note: I use CDbl(currentDate) to avoid problems with Date formats (MS Access stores dates as double values, with the integer part representing days and the decimal part representing fractions of days)
Hope this helps you

Resources