Vb.net grabbing time from sql server and formatting it wrong - vb.net

I run this command in vb
select tuid, finish_time, bay
from orders_table
where tuid between 1001 and 1005 order by finish_time asc
which returns
tuid finish_time bay
1005 2011-10-14 00:20:00.000 5
then I run this command in vb
While commander.Read()
str = "update orders_table set start_time = (" & commander("finish_time") & ") where orders_table.tuid =" & num & ""
Dim myCommand3 As SqlCommand = New SqlCommand(str, myConn2)
myCommand3.ExecuteNonQuery()
When I do the debugger to see what str is sending to the database I get this
str "update orders_table set start_time = (10/14/2011 12:20:00 AM) where orders_table.tuid =1006" String
It throws an error saying incorrect syntax near "12"
It formatting datetime and I don't want it to... how can i fix it so it looks like this
2011-10-14 00:20:00.000

Here is a safe and working version of your current code:
str = "UPDATE orders_table SET start_time = #start_time WHERE orders_table.tuid = #num"
Dim myCommand3 As New SqlCommand(str, myConn2)
myCommand3.Parameters.Add("#start_time", SqlDbType.DateTime)
myCommand3.Parameters.Add("#num", SqlDbType.Int)
While commander.Read()
myCommand3.Parameters(0).Value = commander("finish_time")
myCommand3.Parameters(1).Value = num
myCommand3.ExecuteNonQuery()
End While
But an even better way is to re-write your sql so that it all happens on the server, and you never even read the your select results back to client code. You can write that all in one sql statement.

Instead of () you can use ' or # to delimit the DateTime:
str = "update orders_table set start_time = '" & commander("finish_time") & "' where orders_table.tuid =" & num & ""
This is not the recommended way of using SQL, however (string concatenation), as it opens your code up to SQL Injection.
It is much better to use parameterized queries, this will avoid the whole issue of escaping the values as well. See the answer #JoelCoehoorn gave.

you are formating the string with this (I assume this!)
commander("finish_time")
Just don't format it, or format it like in the database, but the difference lies in how you format it..

Related

Filter between dates VB.NET and Access database

As the title says, I'm unable to filter an SQL sentence from access database with vb.net
Dim data1 As String = DateTimePicker1.Value.ToShortDateString
Dim data2 As String = DateTimePicker2.Value.ToShortDateString
Dim sql As String = "SELECT totais.* From totais Where totais.data Between #" + data1 + "# And #" + data2 + "#;"
It gives me random values. If i put 1-10(October)-2019 it gives me all the records in system, if i put 12-10(October)-2019 it only gives today's record (doesn't show yesterday and before records). I'm not finding the problem, can you please help?
Thanks
I would use Parameters instead of concatenating a string for the Sql statement. It makes the statement much easier to read and avoids syntax errors.
With OleDb the order that parameters appear in the sql statement must match the order they are added to the parameters collection because OleDb pays no attention to the name of the parameter.
Private Sub OPCode()
Dim sql As String = "SELECT * From totais Where data Between #StartDate And #EndDate;"
Using dt As New DataTable
Using cn As New OleDbConnection("Your connection string"),
cmd As New OleDbCommand(sql, cn)
cmd.Parameters.Add("#StartDate", OleDbType.Date).Value = DateTimePicker1.Value
cmd.Parameters.Add("#EndDate", OleDbType.Date).Value = DateTimePicker2.Value
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
DataGridView1.DataSource = dt
End Using
End Sub
You need to use single quotes and convert type in SQL like this:
SELECT totais.* FROM totais WHERE totais.data Between CDATE('" + data1 + "') And CDATE('" + data2 + "');"
You should use parameters as per Mary's answer BUT for completeness...
Ms/Access requires dates specified as #mm/dd/yy# so your SQL will only work properly where the local date time format is mm/dd/yy. i.e. mostly the US. Otherwise you will have to format your date string.

Access query compare datetime to year only date?

I have the following SQL query in my Access database, connected to SQL Server 2008:
SELECT COUNT(*) as mCount
FROM [Projects]
WHERE [DateProjectSubmitted]>'2014';
This works great and accomplishes exactly what I need.
However, I cannot seem to adapt the query for work within Access within a function I have (all error handling removed):
Public Function getNumberOfYearToDateProjects() As Integer
Dim rsMyRecordSet As ADODB.Recordset
Dim sSql As String
Set rsMyRecordSet = New ADODB.Recordset
sSql = "SELECT COUNT(*) as mCount FROM [Projects] WHERE [DateProjectSubmitted]>#" & Format(Date, "YYYY") & "#"
rsMyRecordSet.Open sSql, CurrentProject.Connection
getNumberOfYearToDateProjects = rsMyRecordSet.Fields("mCount")
End Function
I know Access wants # symbols in the date expression but I cannot seem to make it recognize 2014 as a date for purposes of comparison.
If I copy the SQL directly, I run into problems with data mismatches.
I could do the following, but this just seems ugly
sSql = "SELECT COUNT(*) as mCount FROM [Projects] WHERE [DateProjectSubmitted]>#" & DateSerial(Year(Date), 1, 1) & "#"
Can I modify the SQL query or do I need to use something like DateSerial to create a fake 2014-01-01 date for the comparison?
Assuming that DateProjectSubmitted is a date field, and yourYear is a number
SELECT COUNT(*) as mCount FROM [Projects] WHERE YEAR([DateProjectSubmitted]) > " & yourYear

MS Access SELECT query DatePart

i have some problem with my SELECT Query to MS Access .mdb file.
i am using VB.Net and have to send query like..
"SELECT d_date, d_tons, d_qty, d_cost FROM [deal] WHERE DatePart(""m"", [d_date]) = '" _
+ DTP.Value.Month.ToString + "' AND ([d_client] = '" + cBoxClient.Text + "')"
But it doesn't work.. No Error in compiling but this Query cannot SELECT any data.
DTP is DateTimePicker, i select Month with DTP and filled some text into cBoxClient(ComboBox)
What's wrong with that Query? i have no idea because i always used MySQL and this is my first application development with MS Access..
Please HELP me.
Use parameterized query, that will save you from sql injection and complexity of converting specific data format (such as DateTime) to it's string representation that is valid according to database specific culture. For example :
Dim queryString = "SELECT d_date, d_tons, d_qty, d_cost FROM [deal] WHERE " & _
"DatePart(""m"", [d_date]) = ? AND ([d_client] = ?)"
OleDbCommand cmd = New OleDbCommand(queryString, connection)
cmd.Parameters.AddWithValue("#date", DTP.Value.Month)
cmd.Parameters.AddWithValue("#client", cBoxClient.Text)

where clause in select statement - datetime issues

I want to put a where clause in my select statement based on the year and month of a timestamp field in my db
I have a month and a year dropdownlist which give me the following string 01/2012
The date format in my db is "2012-01-01 00:00:00" but when I select an individual date and put it in a message box it converts to "01/01/2012"
I've altered my select statement below to reflect the converted date. However Im still not given the correct details. Any ideas? Is there a particular format that I need to use when dealing with a timestamp field? Can I even use the "Right" function in a select statement?
Dim newRecordDate As String = val1 & "/" & ComboBox2.SelectedValue
Dim sql2 As String = "Select CatA, CatB, CatC, Cost, Currency, MarketingCode, Comment, RecordDate from vw_tblP_Usage_Details where puid = '" & puid & "' right(RecordDate, 7) = '" & newRecordDate & "'"
I say use parameters and the SqlParameter class to pass parameter values to sql server from .NET client instead of using concatenation and string formatting. It makes life easier.
Something Like This:
Dim myDate As Date = DateTime.Now
Dim sql As String = "Select * from SomeTable where MyDate = #some_param"
Using Command As New SqlClient.SqlCommand(sql)
Command.Parameters.AddWithValue("#some_param", myDate)
Using reader As SqlClient.SqlDataReader = Command.ExecuteReader()
'other code here
End Using
End Using

Can my users inject my dynamic sql?

I'm a desktop developer writing for internal users, so I'm not worried about malicious hackers, but I would like to know if there's anything they could enter when updating a value that would execute sql on the server.
The business defines their content schema and I have a CRUD application for them that doesn't have to be changed when their schema changes because the validation details are table-driven and the updates are with dynamic SQL. I have to support single quotes in their data entry, so when they enter them, I double them before the SQL is executed on the server. From what I've read, however, this shouldn't be enough to stop an injection.
So my question is, what text could they enter in a free-form text field that could change something on the server instead of being stored as a literal value?
Basically, I'm building an SQL statement at runtime that follows the pattern:
update table set field = value where pkField = pkVal
with this VB.NET code:
Friend Function updateVal(ByVal newVal As String) As Integer
Dim params As Collection
Dim SQL As String
Dim ret As Integer
SQL = _updateSQL(newVal)
params = New Collection
params.Add(SQLClientAccess.instance.sqlParam("#SQL", DbType.String, 0, SQL))
Try
ret = SQLClientAccess.instance.execSP("usp_execSQL", params)
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
Return ret
End Function
Private Function _updateSQL(ByVal newVal As String) As String
Dim SQL As String
Dim useDelimiter As Boolean = (_formatType = DisplaySet.formatTypes.text)
Dim position As Integer = InStr(newVal, "'")
Do Until position = 0
newVal = Left(newVal, position) + Mid(newVal, position) ' double embedded single quotes '
position = InStr(position + 2, newVal, "'")
Loop
If _formatType = DisplaySet.formatTypes.memo Then
SQL = "declare #ptrval binary(16)"
SQL = SQL & " select #ptrval = textptr(" & _fieldName & ")"
SQL = SQL & " from " & _updateTableName & _PKWhereClauses
SQL = SQL & " updatetext " & _updateTableName & "." & _fieldName & " #ptrval 0 null '" & newVal & "'"
Else
SQL = "Update " & _updateTableName & " set " & _fieldName & " = "
If useDelimiter Then
SQL = SQL & "'"
End If
SQL = SQL & newVal
If useDelimiter Then
SQL = SQL & "'"
End If
SQL = SQL & _PKWhereClauses
End If
Return SQL
End Function
when I update a text field to the value
Redmond'; drop table OrdersTable--
it generates:
Update caseFile set notes = 'Redmond''; drop table OrdersTable--' where guardianshipID = '001168-3'
and updates the value to the literal value they entered.
What else could they enter that would inject SQL?
Again, I'm not worried that someone wants to hack the server at their job, but would like to know how if they could accidentally paste text from somewhere else and break something.
Thanks.
Regardless of how you cleanse the user input increasing the attack surface is the real problem with what you're doing. If you look back at the history of SQL Injection you'll notice that new and even more creative ways to wreak havoc via them have emerged over time. While you may have avoided the known it's always what's lurking just around the corner that makes this type of code difficult to productionize. You'd be better to simply use a different approach.
You can also evaluate an alternative solution. Dynamic generation of SQL with parameters. Something like this:
// snippet just for get the idea
var parameters = new Dictionary<string, object>();
GetParametersFromUI(parameters);
if (parameters.ContainsKey("#id")) {
whereBuilder.Append(" AND id = #id");
cmd.Parameters.AddWithValue("#id", parameters["#id"]);
}
...
Assuming you escape string literals (which from what you said you are doing), you should be safe. The only other thing I can think of is if you use a unicode-based character set to communicate with the database, make sure the strings you send are valid in that encoding.
As ugly as your doubling up code is (:p - Try String.Replace instead.) I'm pretty sure that will do the job.
The only safe assumption is that if you're not using parameterized queries (and you're not, exclusively, here, because you're concatenating the input string into your sql), then you're not safe.
You never never ever never want to build a SQL statement using user input that will be then directly executed. This leads to SQL injection attacks, as you've found. It would be trivial for someone to drop a table in your database, as you've described.
You want to use parameterized queries, where you build an SQL string using placeholders for the values, then pass the values in for those parameters.
Using VB you'd do something like:
'Define our sql query'
Dim sSQL As String = "SELECT FirstName, LastName, Title " & _
"FROM Employees " & _
"WHERE ((EmployeeID > ? AND HireDate > ?) AND Country = ?)"
'Populate Command Object'
Dim oCmd As New OledbCommand(sSQL, oCnn)
'Add up the parameter, associated it with its value'
oCmd.Parameters.Add("EmployeeID", sEmpId)
oCmd.Parameters.Add("HireDate", sHireDate)
oCmd.Parameters.Add("Country", sCountry)
(example taken from here) (also not I'm not a VB programmer so this might not be proper syntax, but it gets the point across)