SQL injection method for select statement - sql

I want to get same values form my database therefore I'm using this query:
SELECT NormalComputers
FROM usb_compliance
WHERE ATC = 'CMB'
ORDER BY date DESC
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
Using this I want to get so many values so I plan to use SQL injection method please help me how to create this
If I can use injection method I can use function it should be like this
Private Function query(ByVal values As String, ByVal atc As String, ByVal no As Integer)
Dim connetionString As String
Dim connection As SqlConnection
Dim command As SqlCommand
Dim sql As String
connetionString = "Server=CTV-WEBDEVEXG;Database=usb;Trusted_Connection=True;"
sql = "SELECT #values FROM usb_compliance WHERE ATC=#atc ORDER BY date DESC OFFSET #no ROWS FETCH NEXT 1 ROWS ONLY"
connection = New SqlConnection(connetionString)
Try
command = New SqlCommand(sql, connection)
With command
.Connection.Open()
MsgBox("done !!!")
.CommandType = CommandType.Text
.Parameters.Add("#values", SqlDbType.DateTime).Value = values
.Parameters.Add("#atc", SqlDbType.NVarChar).Value = atc
.Parameters.Add("#NormalComputers", SqlDbType.Int).Value = no
End With
command.ExecuteNonQuery()
command.Dispose()
connection.Close()
Catch ex As Exception
End Try
Return sql
End Function
I have tried this way but its not working so please help me on this

parameter #values refers to the name of the field you want to retrieve. So it owes to be a string not a DateTime (despite the fact that this filed datatype might be DateTime).
...
.Parameters.Add("#values", SqlDbType.NVarChar).Value = values
...
to get rows affected:
Dim numRows as Integer
...
..
numRows=command.ExecuteNonQuery()

Related

Select max value in MS Access database

I need to select the max value in my row column. When I hit line
(FindCurrentTimeCard = Val(myreader("Row"))
I get an error:
System.IndexOutOfRangeException
Code:
Public Function FindCurrentTimeCard() As Integer
Dim myconnection As OleDbConnection = New OleDbConnection
Dim query As String = "Select MAX(Row) from Table2"
Dim dbsource As String =("Provider=Microsoft.ACE.OLEDB.12.0;DataSource=S:\Docs\PRODUCTION\Shop Manager\Shop_Manager\Shop_Manager\Database2.accdb;")
Dim conn = New OleDbConnection(dbsource)
Dim cmd As New OleDbCommand(query, conn)
Try
conn.Open()
Dim myreader As OleDbDataReader = cmd.ExecuteReader()
myreader.Read()
FindCurrentTimeCard = Val(myreader("Row"))
conn.Close()
Catch ex As OleDbException
MessageBox.Show("Error Pull Data from Table2")
FindCurrentTimeCard = 1
End Try
End Function
Table2
The issue is that when you evaluate an aggregate function (or indeed, any expression performing some operation on a field or fields), the result of such evaluation will be assigned an alias (such as Expr1000) unless an alias is otherwise stated.
Hence, when you evaluate the SQL statement:
select max(table2.row) from table2
MS Access will return the result assigned to an alias such as Expr1000:
Hence, the SQL statement does not output a column named Row, causing your code to fail when attempting to retrieve the value of such column:
FindCurrentTimeCard = Val(myreader("Row"))
Instead, you should specify an alias to which you may refer in your code, e.g.:
select max(table2.row) as maxofrow from table2
With your function then returning the value associated with such column:
FindCurrentTimeCard = Val(myreader("maxofrow"))
Comments and explanations in-line
Public Function FindCurrentTimeCard() As Integer
Dim CurrentTimeCard As Integer
'The Using block ensures that your database objects are closed and disposed
'even it there is an error
'Pass the connection string directly to the connection constructor
Using myconnection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;DataSource=S:\Docs\PRODUCTION\Shop Manager\Shop_Manager\Shop_Manager\Database2.accdb;")
Dim query As String = "Select MAX(Row) from Table2"
Using cmd As New OleDbCommand(query, myconnection)
Try
myconnection.Open()
'since you are only retrieving a single value
'you can used .ExecuteScalar which gets the value
'in the first row, first column
CurrentTimeCard = CInt(cmd.ExecuteScalar)
Catch ex As OleDbException
MessageBox.Show("Error Pull Data from Table2")
End Try
End Using
End Using
'vb.net uses the Return statement to return the value of the function
Return CurrentTimeCard
End Function

Taking one value from a table

sorry if this has been asked before but I everything I found has not helped.
I'm looking to set a value from a table to the text property of a label. This is what I have so far:
In a separate class with the connection string "conn" -
(SQL Region)
Public Const SELECT_1 As String = "SELECT TOP 1 * FROM [TableTimes]
WHERE [timeID] = #PKey"
(Methods Region)
Public Shared Function returnOneRow(PrimaryKey As Integer) As TableTimes
Dim returnRow As New TableTimes(0)
Dim conn As New SqlConnection
conn.connectionstring = Conn.getConnectionString
Dim command As New SqlCommand
command.connection = conn
command.CommandType = CommandType.Text
command.CommandText = SQL.SELECT_1
command.Parameters.AddWithValue("#PKey", PrimaryKey)
Try
conn.Open()
Dim dR As IDataReader = command.ExecuteReader
If dR.Read() Then
returnRow.timeID = PK
If Not IsDBNull(dR(Fields.linkID)) Then returnRow.linkID = dR(Fields.linkID)
If Not IsDBNull(dR(Fields.dateTime)) Then returnRow.dateTime = dR(Fields.dateTime)
End If
Catch ex As Exception
Console.WriteLine(Err.Description)
End Try
Return returnRow
End Function
And then back in the main form I am trying to set the dateTime to a label based on what primary key (timeID) I enter as a parameter. This is the closest I can think of:
label.Text = (Tables.TableTimes.returnOneRow(1).dateTime).ToString
I know the output should be "2016-02-04 10:00:00" for the row with the timeID of 1 based on my table data, but instead it returns "0001-01-01 12:00:00" no matter what parameter I enter.
I would prefer to not change my method or sql statement and just change how I call the function in the main form if that's possible.
Thank you!

How can I read a specific column in a database?

I hava a Table named DTR_Table it has 8 columns in it namely:
EmployeeID,Date,MorningTime-In,MorningTime-Out,AfternoonTime-In,AfternoonTime-Out,UnderTime,Time-Rendered.I want to read the column "AfternoonTime-In".
Following is my code. It reads my "AfternoonTime-In" field, but it keeps on displaying "Has Rows" even if there is nothing in that column.
How can I fix this?
Connect = New SqlConnection(ConnectionString)
Connect.Open()
Dim Query1 As String = "Select [AfternoonTime-Out] From Table_DTR Where Date = #Date and EmployeeID = #EmpID "
Dim cmd1 As SqlCommand = New SqlCommand(Query1, Connect)
cmd1.Parameters.AddWithValue("#Date", DTRform.datetoday.Text)
cmd1.Parameters.AddWithValue("#EmpID", DTRform.DTRempID.Text)
Using Reader As SqlDataReader = cmd1.ExecuteReader()
If Reader.HasRows Then
MsgBox("Has rows")
Reader.Close()
Else
MsgBox("empty")
End If
End Using`
After returning the DataReader you need to start reading from it if you want to extract values from your query.
Dim dt = Convert.ToDateTime(DTRform.datetoday.Text)
Dim id = Convert.ToInt32(DTRform.DTRempID.Text)
Using Connect = New SqlConnection(ConnectionString)
Connect.Open()
Dim Query1 As String = "Select [AfternoonTime-Out] From Table_DTR
Where Date = #Date and EmployeeID = #EmpID"
Dim cmd1 As SqlCommand = New SqlCommand(Query1, Connect)
cmd1.Parameters.Add("#Date", SqlDbType.DateTime).Value = dt
cmd1.Parameters.Add("#EmpID", SqlDbType.Int).Value = id
Using Reader As SqlDataReader = cmd1.ExecuteReader()
While Reader.Read()
MessageBox.Show(Reader("AfternoonTime-Out").ToString())
Loop
End Using
End Using
Note that I have changed the AddWithValue with a more precise Add specifying the parameter type. Otherwise, your code will be in the hand of whatever conversion rules the database engine decides to use to transform the string passed to AddWithValue to a DateTime.
It is quite common for this conversion to produce invalid values especially with dates

Assign null value to a decimal field in SQL

I want to assign null value in a field in SQL 2014 which has a data type, decimal. I tried to use theses codes but I didn't get the way I wanted (providing that other fieldnames and values are present.)
query = "INSERT INTO DBNAME.TLTRPRGP(DECIMALVAL) VALUES(#DECIMALVAL)"
params = New String() {"BLGSCD"}
values = New String() {Nothing}
SaveUpdateDelete(query, params, values)
query = "INSERT INTO DBNAME.TLTRPRGP(DECIMALVAL) VALUES(#DECIMALVAL)"
params = New String() {"BLGSCD"}
values = New String() {DbNull.Value}
SaveUpdateDelete(query, params, values)
query = "INSERT INTO DBNAME.TLTRPRGP(DECIMALVAL) VALUES(#DECIMALVAL)"
params = New String() {"BLGSCD"}
values = New String() {VbNull}
SaveUpdateDelete(query, params, values)
Private Sub SaveUpdateDelete(ByVal sql As String, ByVal parameters() As String, ByVal Values() As String)
If con.State = ConnectionState.Open Then
con.Close()
End If
con.Open()
Dim command As New SqlCommand
command = New SqlCommand(sql, con)
For i = 0 To parameters.Count - 1
command.Parameters.AddWithValue("#" & parameters(i).ToString, Values(i))
Next
command.CommandText = sql
command.ExecuteNonQuery()
con.Close()
End Sub
The first code returns 0. The second returns syntax error saying "Value System.DbNull.Value cannot be converted to String". The third code returns 1. All these codes failed to return the right value which is suppose to be NULL or EMPTY. What else is there to try?
the issue is with the datatype of the values: you constrain it to be a string but there are values that cannot be converted to strings (eg: DBNull.Value).
the solution is to use the generic object as the datatype for the parameters passed to the function SaveUpdateDelete.

get column value according to another column value from datatable in vb.net

i have a datatable similar to this:
id msg
1 thank you..
2 kindly...
3 please insert..
4 please stop
i need to get a msg according to a specific id from the datatable that's how i'm filling my datatable:
msgTable = selectMsg()
MsgBox(i need to get the msg here)
Public Function selectMsg() As DataTable
Dim command As SqlCommand = New SqlCommand("selectMsg", cn)
command.CommandType = CommandType.StoredProcedure
Dim da As New SqlDataAdapter(command)
'If dt.Rows.Count <> 0 Then
' dt.Rows.Clear()
'End If
Try
da.Fill(msgDS, "N_AI_HOME_CARE")
msgDT = msgDS.Tables(0)
Catch ex As Exception
logFile("SP selectMsg ---" + ex.Message)
End Try
Return msgDT
End Function
any suggestion will be much appreciated !
Supposing that your stored procedure returns the whole datatable of your messages (a very bad move because if the table is big you could have performance and network problems) then you need to apply the Select method with a filter expression to your returned datatable
msgTable = selectMsg()
Dim rows() = msgTable.Select("ID = " & idOfMessage)
if rows.Length > 0 then
MsgBox(row(0)(1).ToString()) ' read the first row, second column of the table'
End If
But I think you should use a more correct approach using a simple ExecuteScalar that doesn't return the entire datatable but just the first row and first column of a query
Public Function selectMsg(idOfMessage as Integer) As String
Dim command As SqlCommand = New SqlCommand("SELECT msg from tableName where ID = #id", cn)
command.Parameters.AddWithValue("#id", idOfMessage)
Dim result = command.ExecuteScalar()
if string.IsNullOrEmpty(result) Then
result = "No message found"
End If
return result
End Function
well acctually i just found that you use
MsgBox(msgTable.Rows(0)(1).ToString())
without any select method :)