Everybody seems to hate DateTime values.
In my project, I have a SQL SELECT query to find results in the database matching the parameter values.
The code I have is:
Dim where As String = "WHERE [Supp_Code] = #scode " & _
"AND [DateFrom] = #datfrom " & _
"AND [DateTo] = #datto " & _
"AND [Comm_Code] = #ccode " & _
"AND [Customer_Code] = #custcode "
Dim sql As String = "SELECT [Comm_Code], [AqYear] FROM [Acquisition Commission] "
sql &= where & " ORDER BY [AqYear] ASC"
Dim cmd As New OleDb.OleDbCommand(sql, con)
cmd.Parameters.AddWithValue("#scode", cmbSupp.Text.Trim)
cmd.Parameters.AddWithValue("#datfrom", datFrom.Value)
cmd.Parameters.AddWithValue("#datto", datTo.Value)
cmd.Parameters.AddWithValue("#ccode", txtCommCode.Text)
cmd.Parameters.AddWithValue("#custcode", cmbCustomerCode.Text)
Dim daYear As New OleDb.OleDbDataAdapter(cmd)
Dim dsYear As New DataSet
daYear.Fill(dsYear)
The code itself has no issues. The issue is that the DataSet only ever has 0 rows, because the DateTime format of datFrom.Value (which is a DateTimePicker control) is 'MM/dd/yyyy', but in the database it is stored as 'dd/MM/yyyy'.
What's the easiest way of converting it the correct database format before using it as a parameter?
EDIT
Using the comments/answers below, I've adapted my code to the following:
Dim test As DateTime
Dim test2 As DateTime
test = ugDates.ActiveRow.Cells("DateFrom").Value
test = ugDates.ActiveRow.Cells("DateTo").Value
Try
Dim where As String = "WHERE [Supp_Code] = #scode " & _
"AND [DateFrom] = #datfrom " & _
"AND [DateTo] = #datto " & _
"AND [Comm_Code] = #ccode " & _
"AND [Customer_Code] = #custcode "
Dim sql As String = "SELECT DISTINCT [Comm_Code], [AqYear] FROM [Acquisition Commission] "
sql &= where & " ORDER BY [AqYear] ASC"
Dim cmd As New OleDb.OleDbCommand(sql, con)
cmd.Parameters.Add("#scode", OleDbType.VarChar).Value = cmbSupp.Text
cmd.Parameters.Add(New OleDbParameter("#datfrom", OleDbType.Date).Value = test)
cmd.Parameters.Add(New OleDbParameter("#datto", OleDbType.Date).Value = test2)
cmd.Parameters.Add("#ccode", OleDbType.VarChar).Value = txtCommCode.Text
cmd.Parameters.Add("#custcode", OleDbType.VarChar).Value = cmbCustomerCode.Text
But, it gives me the following error on the second parameter:
The OleDbParameterCollection only accepts non-null OleDbParameter type objects, not Boolean objects.
The issue is that the DataSet only ever has 0 rows, because the DateTime format of datFrom.Value (which is a DateTimePicker control) is 'MM/dd/yyyy', but in the database it is stored as 'dd/MM/yyyy'.
That is probably NOT the issue unless you are storing the date as a string. A date is a structure, not a string, and inherently does not have formatting. Formatting is something that is applied to a string. Its similar to a number like an int or decimal. If this field is indeed a string you should revisit your schema and update the type accordingly.
Most likely you are trying to compare a date with time either in the value of the parameter OR in the value of the query.
Use DateValue function to trim the time of the stored database
Use .Date on the date value to only compare the value date
Code:
Dim where As String = "WHERE [Supp_Code] = #scode " & _
"AND DateValue([DateFrom]) = #datfrom " & _
"AND DateValue([DateTo]) = #datto " & _
"AND [Comm_Code] = #ccode " & _
"AND [Customer_Code] = #custcode "
// select either OleDbType.Date or OleDbType.DBDate
cmd.Parameters.Add(new OleDbParameter("#datfrom", OleDbType.Date) With {.Value = datFrom.Value.Date})
cmd.Parameters.Add(new OleDbParameter("#datto", OleDbType.Date) With {.Value = datTo.Value.Date})
The other possible problem is the logic, why not do a between or range check instead of an equality check on DateFrom and DateTo?
"AND DateValue([DateFrom]) >= #datfrom " & _
"AND DateValue([DateTo]) <= #datto " & _
Ideally you would use the same value here for both #datfrom and #datto. The query above would be any item that has a start/end date that span the passed in date parameter.
Related
I found the following query in order to find out if a database table was created already or not:
if db_id('thedbName') is not null
--code mine :)
print 'db exists'
else
print 'nope'
Now I am wanting to use that same query within my VB.net application. This is the code I currently have elsewhere that connects to the database (that I am wanting to see if its there before doing all this):
Dim cn As SqlConnection = New SqlConnection("Data Source=DAVIDSDESKTOP;" & _
"Initial Catalog=thedbName;" & _
"Integrated Security=True;" & _
"Pooling=False")
Dim sql As String = "if db_id('thedbName') is not null " & vbCrLf & _
"Print() 'exists' " & vbCrLf & _
"else " & vbCrLf & _
"Print() 'nope'"
Dim cmd As SqlCommand = New SqlCommand(sql, cn)
cmd.Connection.Open()
Dim blah As String = cmd.ExecuteNonQuery()
cmd.Connection.Close()
Of course the issue with this is that I have to know the database name first in order to connect to the database.
I then seem to be able to connect to the master database using this:
Dim cn As SqlConnection = New SqlConnection("Data Source=DAVIDSDESKTOP;" & _
"Integrated Security=True;" & _
"Pooling=False")
Dim sql As String = "if db_id('thedbName') is not null " & vbCrLf & _
"Print() 'exists' " & vbCrLf & _
"else " & vbCrLf & _
"Print() 'nope'"
Dim cmd As SqlCommand = New SqlCommand(sql, cn)
cmd.Connection.Open()
Dim blah As String = cmd.ExecuteNonQuery()
cmd.Connection.Close()
But that query seems to throw an error on Dim blah As String = cmd.ExecuteNonQuery() of:
Additional information: Incorrect syntax near ')'.
So I'm not all sure what I am missing in order to correct the issue with the query?
Need to know how to have the query come back and say 'exists' or 'nope'
Change Print() to Print (remove the parentheses.)
Better, don't use Print at all, use select.
Dim sql As String = "if db_id('thedbName') is not null " & vbCrLf & _
"select 'exists' " & vbCrLf & _
"else " & vbCrLf & _
"select 'nope'"
Dim blah As String = CType(cmd.ExecuteScalar(), string)
ExecuteNonQuery returns the number of affected rows for updates and inserts. But what you are executing is a query.
ExecuteScalar returns the first column of the first row selected. The query above only returns one row with one value, so that's what it will return.
or do it like this
select * from sys.databases where [name] = 'thedbName'
if it returns a row, then the database exists, if not then it doesn't.
To check if a table exists within a database, use this
select * from sys.objects where [name] = 'theTableName' and type_desc = 'USER_TABLE'
I'm using basic date picker for vb.net and oracle as my database. when i insert the date from basic date picker, i got this error >> ORA-01797: this operator must be followed by ANY or ALL
this is my code :
Private Function GetDate(ByVal bdp1 As Date) As DataSet
Dim connectionString As String = "Data Source = ***; User ID =***; Password =**;"
Dim sqlConnection As OracleClient.OracleConnection = New OracleClient.OracleConnection(connectionString)
Dim queryString As String = "select * from smsdw.lot_act where tran_dttm <= ('" & bdp1 & "' , 'MM/DD/YYYY') and tran_dttm > ('" & bdp1 & "', 'MM/DD/YYYY')"
Dim sqlCommand As OracleClient.OracleCommand = New OracleClient.OracleCommand(queryString, sqlConnection)
sqlCommand.CommandTimeout = 0
Dim dataAdapter As OracleClient.OracleDataAdapter = New OracleClient.OracleDataAdapter(sqlCommand)
Dim dataSet As DataSet = New DataSet
dataAdapter.Fill(dataSet)
Return dataSet
End Function
Try, instead:
Dim queryString As String = "select * from smsdw.lot_act where tran_dttm <= :dtm1 and tran_dttm > :dtm2"
Dim sqlCommand As OracleClient.OracleCommand = New OracleClient.OracleCommand(queryString, sqlConnection)
sqlCommand.Parameters.AddWithValue("dtm1",bdp1)
sqlCommand.Parameters.AddWithValue("dtm2",bdp1)
Which a) avoids the possibility of SQL injection, and b) Keeps the date as a date throughout, rather than mangling it to/from a string.
It doesn't fix the logical issue with your query though - where you're trying to find a row where tran_dttm is both "less than or equal" and "greater than" the same value.
Try this ..
Dim queryString As String = "select * from smsdw.lot_act where tran_dttm <= cdate('" & bdp1.Value.ToString & "') and tran_dttm > cdate('" & bdp1.Value.ToString & "')"
Try this:
Dim queryString As String = "select * from smsdw.lot_act where tran_dttm <= '" & bdp1.ToString("MM/dd/yyyy") & "' and tran_dttm > '" & bdp1.ToString("MM/dd/yyyy") & "'"
But for oracle the default datetime format is YYYY-MM-DD. You have three options:
Change the default file format for the one that suits your desires
Use the default format: bdp1.ToString("yyyy-MM-dd")
Use the todate oracle function specifiying the read format:
" to_date('" & bdp1.ToString("MM/dd/yyyy") & "', 'mm/dd/yyyy') "
hello I'm using oracle & vb.net
this is my code for select statement and I want to display the selected date from interface which i use Basic Date Picker and i assign that as bdp1
Dim queryString As String = "select * from abc where (tran_dttm <= to_date( '" & bdp1 & "' ,'MM/DD/YYYY') and tran_dttm > to_date( '" & bdp1 & "' ,'MM/DD/YYYY')and lpt = '" & ListBox1 & "' and device = '" & strMaterial & "')"
select * from abc where trunc (tran_dttm) = to_date('" & bdp1 & "','MM/DD/YYYY')
Parameters should be prefixed with the : and should be included as text directly in the command. It is the job of the framework to pass them with their values to the database engine
Private Function GetDate(ByVal strMaterial As String, ByVal ListBox1 As String, ByVal bdp1 As Date) As DataSet
Dim connectionString As String = "Data Source = ***; User ID = ***; Password = **;"
Dim queryString As String = "BEGIN select * from abc " & _
"where (tran_dttm <= to_date(:bdp1,'MM/DD/YYYY') and " & _
"tran_dttm > to_date(:bdp1 ,'MM/DD/YYYY') and " & _
"lpt = :lb1 and device = :mat); END;"
Using sqlConnection = New OracleClient.OracleConnection(connectionString)
Using sqlCommand = New OracleClient.OracleCommand(queryString, sqlConnection)
sqlCommand.CommandTimeout = 0
sqlCommand.Parameters.Add(New OracleParameter(":bdp1", OracleType.DateTime)).Value = bdp1
sqlCommand.Parameters.Add(New OracleParameter(":lb1", OracleType.VarChar)).Value = lstBox1.SelectedItem.ToString
sqlCommand.Parameters.Add(New OracleParameter(":mat1", OracleType.VarChar)).Value = strMaterial
Dim dataAdapter As OracleClient.OracleDataAdapter = New OracleClient.OracleDataAdapter(sqlCommand)
Dim dataSet As DataSet = New DataSet
dataAdapter.Fill(dataSet)
Return dataSet
End Using
End Using
End Function
The ListBox1 is wrong if it is a control. You should use the SelectedItem property as value for the parameter (a bit of error checking is needed though)
i am facing very strange problem , I am using the following piece of code but ds is not filled some times there is data in the ds but not always, I have change the connection pool and also restart the iis but no luck at all , I am not able to find where the problem is please help me out.
I am running the same query in the TOAD and its giving result , I have also commit the transaction for if any thing in inconsistent.
Dim command As New OracleCommand
Dim ds As New DataSet
Try
Using connection As New OracleConnection
(ConfigurationManager.ConnectionStrings("CA").ConnectionString.ToString())
connection.Open()
command.Connection = connection
command.CommandText = "SELECT w.portfolio, w.appl_group,
tm.trng_title, p.tt_program_title," & _
" p.created_date,
p.tt_target_completion_date, p.tt_prog_status," & _
" w.emp_id, w.first_name || ' ' ||
w.last_name, ('Y') training_done_flag," & _
" t.actual_completion_date,
p.created_by, w.people_manager, " & _
" w.project_manager, w.flag" &
_
" FROM tt_training_done_records t," & _
" wsr_employee w, " & _
" tt_training_master tm, " & _
" tt_newprogram p" & _
" WHERE(w.emp_id = t.employee_id)" & _
" AND t.training_info_id = tm.trng_id"
& _
" AND p.tt_program_id(+) =
t.program_id" & _
" AND tm.trng_id IN ( 'TT_009' ) " & _
" AND t.actual_completion_date BETWEEN
TO_DATE('11-Mar-2009') AND TO_DATE('11-Mar-2013') " & _
" "
Dim adpt As New OracleDataAdapter(command)
adpt.AcceptChangesDuringFill = False
adpt.Fill(ds)
connection.Close()
End Using
Don't rely on the default behavior of casting a string into a date. Either use a date literal or provide the format string argument. This introduces a dependency on NLS environment settings your .NET code should not depend upon.
Instead of TO_DATE('11-Mar-2013')
Try date '2013-03-11' or TO_DATE('11-Mar-2013'), 'DD-Mon-YYYY')
The error is: Conversion failed when converting date and/or time from character string.
Basically I'm trying to make it so that when someone clicks a location in a list box it increments the correct field in a Stats table by 1 to say that they clicked the location. I've been trying to solve this for a while now and can't get anywhere. My date is in date format, and so is the Date field in my Stats table. My code can be seen below.
Dim Current As String
Dim Check As String
Dim objCmd2 As Object
Dim iCount As Integer
Dim tDate As Date
Current = LocBox.SelectedItem
Check = LocList.FindString(Current)
If Check > -1 Then
MsgBox("You have already selected this place to visit")
Else
LocList.Items.Add(Current)
ObjDataReader.Close()
tDate = Date.Today
MessageBox.Show(tDate)
tDate = tDate.ToString()
objCmd2 = New SqlCommand("SELECT " & Replace(Current, " ", "_") & " FROM Stats WHERE Date = '" & tDate & "'", objConn)
ObjDataReader = objCmd2.ExecuteReader
If ObjDataReader.HasRows Then
ObjDataReader.Read()
If ObjDataReader(0) Is DBNull.Value Then
iCount = 0
Else
iCount = ObjDataReader(0)
End If
Else
iCount = 0
End If
objCmd = New SqlCommand("INSERT INTO Stats(Date," & Replace(Current, " ", "_") & ") Values('" & tDate.Date & "'," & iCount & " )", objConn)
ObjDataReader.Close()
objCmd.ExecuteNonQuery()
objConn.Close()
Thanks in advance.
The issue comes in with the second SQL statement I think. I don't understand why adding a date into a date field would be an issue, I've tried adding it as a string which didn't work. Thanks for all the answers so far.
As Martin points out this is probably the best choice:
int colnum = ConvertColumnNameToNumber(Current)
objCmd2 = New SqlCommand("SELECT "+colnum.ToString()+" FROM Stats WHERE [Date] = #inDate", objConn)
objCmd2.Parameters.Add("#inDate",SqlDbType.DateTime).value = tDate
Not tested or compiled might have typos.
Note the use of colnum above. Because you can't use parameters for column names you have to use the column number. If you have code that returns an integer as a return value you can protect against injection (it can only a number).
I'm going to guess the issue is here: MessageBox.Show(tDate)
You need to convert the date to a string using tDate.ToString or whatever other method you want.
Are you getting compile errors? I always code with Option Strict On, and your code would definitely bring up errors where you are not converting variables.
I may be off base but you have tDate as a Date variable type and then your trying to send it a string, you can just use tDate.ToString() in your SqlCommand lines and not convert it first.
Try Removing the apostrophes from around tdate so that it is...
objCmd2 = New SqlCommand("SELECT " & Replace(Current, " ", "_") & " FROM Stats WHERE Date = " & tDate, objConn)
and
objCmd = New SqlCommand("INSERT INTO Stats(Date," & Replace(Current, " ", "_") & ") Values(" & tDate.Date & "," & iCount & " )", objConn)