Search Engine using TextBox, ComboBox and RadioButton - sql-server

I am developing a search engine within WindowsForms,
I'm using VB.Net 2010 and SQL Server 2008,
My connection is ADO.Net
I experience difficulties in concatenating strings whenever I retrieve records from the database using a textbox, combobox and a radiobutton.
I would like to retrieve record based from the values of those objects,
Dim Condition1 As String = TextBox1.Text
Dim Condition2 As String = ComboBox1.Text
Dim Condition3 As String = RadioButton.Text
When I try to concatenate, I use the operator AND..
SELECT * FROM TableName WHERE (Condition1 AND Condition2 AND Conditon3)
It gives me an error when some objects doesnt have a value.
Incorrect syntax near the word AND.

NEVER concatenate strings to make queries! use SQL Parameters! The query you posted is prone to SQL Injection.
Dim query as String = "SELECT * FROM TableName WHERE Column1 = #Column1 AND
Column2 = #Column2 AND Column3 = #Column3"
Dim cmd As SqlCommand
cmd.Parameters.AddWithValue("#Column1", textBox1.Text)
cmd.Parameters.AddWithValue("#Column2", comboBox1.Text)
cmd.Parameters.AddWithValue("#Column3", radioButton1.Text)
Apart from the above, the conditions you are trying to concatenate are not valid. Anything that comes after the WHERE clause should specify the column name and the value like what I did above. So condition1 should be for example :
// If the column type is varchar then single quotes must be used
Dim Condition1 As String = String.Format("Name = '{0}'", TextBox1.Text)

Related

Problems with saving numbers after formatting example "200,000"

I try to save data from TextBox1.Text value to a SQL Server database in column of type Decimal(18, 0). I use VB.NET and SQL Server database.
I format the data in the textbox value to number for example "200,000".
When I try to save, I get this error
Error converting nvarchar to numeric
I can't use Val(Textbox1.text) because he take only "200" not "200000"
How can I fix this?
18 precision 0 scale is essentially a Long, so you should use Long.Parse() or Long.TryParse() to get the real numeric value in VB. This will give you more control than the antiquated Val() over things like separator characters.
Then, in the SQL part, make sure you're using a parameterized query with the appropriate type for the parameter:
Dim data As Long = Long.Parse(Textbox1.Text)
Dim sql As String = "INSERT INTO [someTable] (column) VALUES (#parameter)"
Using con As New SqlConnection("connection string here")
Using cmd As New SqlCommand(sql, con)
cmd.Parameters.Add("#parameter", SqlDbType.Decimal, 18, 0).Value = data
con.Open()
cmd.ExecuteNonQuery()
End Using

Updating ms access database [duplicate]

I am trying to create an SQL statement using user-supplied data. I use code similar to this in C#:
var sql = "INSERT INTO myTable (myField1, myField2) " +
"VALUES ('" + someVariable + "', '" + someTextBox.Text + "');";
var cmd = new SqlCommand(sql, myDbConnection);
cmd.ExecuteNonQuery();
and this in VB.NET:
Dim sql = "INSERT INTO myTable (myField1, myField2) " &
"VALUES ('" & someVariable & "', '" & someTextBox.Text & "');"
Dim cmd As New SqlCommand(sql, myDbConnection)
cmd.ExecuteNonQuery()
However,
this fails when the user input contains single quotes (e.g. O'Brien),
I cannot seem to get the format right when inserting DateTime values and
people keep telling me that I should not do this because of "SQL injection".
How do I do it "the right way"?
Use parameterized SQL.
Examples
(These examples are in C#, see below for the VB.NET version.)
Replace your string concatenations with #... placeholders and, afterwards, add the values to your SqlCommand. You can choose the name of the placeholders freely, just make sure that they start with the # sign. Your example would look like this:
var sql = "INSERT INTO myTable (myField1, myField2) " +
"VALUES (#someValue, #someOtherValue);";
using (var cmd = new SqlCommand(sql, myDbConnection))
{
cmd.Parameters.AddWithValue("#someValue", someVariable);
cmd.Parameters.AddWithValue("#someOtherValue", someTextBox.Text);
cmd.ExecuteNonQuery();
}
The same pattern is used for other kinds of SQL statements:
var sql = "UPDATE myTable SET myField1 = #newValue WHERE myField2 = #someValue;";
// see above, same as INSERT
or
var sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = #someValue;";
using (var cmd = new SqlCommand(sql, myDbConnection))
{
cmd.Parameters.AddWithValue("#someValue", someVariable);
using (var reader = cmd.ExecuteReader())
{
...
}
// Alternatively: object result = cmd.ExecuteScalar();
// if you are only interested in one value of one row.
}
A word of caution: AddWithValue is a good starting point and works fine in most cases. However, the value you pass in needs to exactly match the data type of the corresponding database field. Otherwise, you might end up in a situation where the conversion prevents your query from using an index. Note that some SQL Server data types, such as char/varchar (without preceding "n") or date do not have a corresponding .NET data type. In those cases, Add with the correct data type should be used instead.
Why should I do that?
It's more secure: It stops SQL injection. (Bobby Tables won't delete your student records.)
It's easier: No need to fiddle around with single and double quotes or to look up the correct string representation of date literals.
It's more stable: O'Brien won't crash your application just because he insists on keeping his strange name.
Other database access libraries
If you use an OleDbCommand instead of an SqlCommand (e.g., if you are using an MS Access database), use ? instead of #... as the placeholder in the SQL. In that case, the first parameter of AddWithValue is irrelevant; instead, you need to add the parameters in the correct order. The same is true for OdbcCommand.
Entity Framework also supports parameterized queries.
VB.NET Example Code
This is the example code for the wiki answer in vb.net, assuming Option Strict On and Option Infer On.
INSERT
Dim sql = "INSERT INTO myTable (myField1, myField2) " &
"VALUES (#someValue, #someOtherValue);"
Using cmd As New SqlCommand(sql, myDbConnection)
cmd.Parameters.AddWithValue("#someValue", someVariable)
cmd.Parameters.AddWithValue("#someOtherValue", someTextBox.Text)
cmd.ExecuteNonQuery()
End Using
UPDATE
Dim sql = "UPDATE myTable SET myField1 = #newValue WHERE myField2 = #someValue;"
' see above, same as INSERT
SELECT
Dim sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = #someValue;"
Using cmd As New SqlCommand(sql, myDbConnection)
cmd.Parameters.AddWithValue("#someValue", someVariable)
Using reader = cmd.ExecuteReader()
' ...
End Using
' Alternatively: Dim result = cmd.ExecuteScalar()
' if you are only interested in one value of one row.
End Using

Sql select statement with two conditions in visual basic

I am trying to retrieve Two Columns; App_ID & App_Slot from a table su_Appointments from an sql server database using vb, and I have two conditions the Date and Time; App_Date & App_Time for the query, now when I run the query it throws an error saying : Incorrect syntax near '2014'. The query is as follows
I am going to store App_ID into the variable AP_ID
CODE
Using Query As New SqlCommand("Select App_ID From su_Appointments Where (App_Date = ' and App_Time = ' )" & DT & TM, sqlcon)
sqlcon.Open()
Dim dr As SqlDataReader = Query.ExecuteReader()
While dr.Read()
AP_ID = dr(0)
End While
End Using
sqlcon.Close()
Well, your syntax is effectively wrong
A SELECT statement requires
SELECT <fieldA>, <FieldB>, ....
FROM <Table>
WHERE <FieldX> = <Condition1> AND <FieldZ> = <Condition2>
But, a part from this basic error, you need to start using a parameterized query approach
Using sqlcon = new SqlConnection(.....connectionstring...)
Dim cmdText = "Select App_ID From su_Appointments Where App_Date =#dt and App_Time = #tm"
Using Query = New SqlCommand(cmdText, sqlcon)
sqlcon.Open()
Query.Parameters.AddWithValue("#dt", DT)
Query.Parameters.AddWithValue("#tm", TM)
Using dr =Query.ExecuteReader()
While dr.Read()
AP_ID = dr(0)
End While
End Using
End Using
End Using
With a parameterized query, you get many benefits. There is no possibility of Sql Injection Attacks, the text of your command is more clear and understandable, the parameters are treated for correct quoting by the code itself so you don't need to check for single quotes inside your strings, or format correctly dates and decimal numbers.
Eventually, you could encounter a different problem. If your columns App_Date and App_Time are of type datetime then you need to pass parameters of the appropriate type, not simply strings. Instead if, these fields are of type nvarchar (or some other kind of text type) then you pass strings but you will have problems storing and querying correctly in these fields.

Inserting a string with any ASCII char (0 to 255) into a VARCHAR field in SQL Server

I am relatively new to SQL Server and am working on a legacy app in Visual Basic 6. How can I use an SQL INSERT command to insert a string of characters that can include any ASCII character between 0 and 255 into a VARCHAR field?
You could encode the string into a sequence of hexadecimal values representing the ASCII codes of the string's characters, put 0x in front of the sequence, then apply CAST(… AS varchar(n)) to the whole thing and use that expression in your DDL statement.
What I mean is, if your string was e.g. #X?!v, you would insert it like this
UPDATE table
SET column = CAST(0x23583F2176 AS varchar(n))
WHERE condition
So, if there was a NUL character somewhere, the resulting sequence would contain 00 at the corresponding position.
I don't really "speak" VB, but if I did, I would perhaps look into creating a function accepting a raw string and returning a string of hex codes, and so, when building the DDL command, my VB instruction would probably look something like this:
cmd.CommandText = "UPDATE table SET column = CAST(0x" & HexEncode(RawString) & " AS varchar(n)) WHERE condition"
Assuming your project has a reference to ADO, it's something like this:
Dim oConn As Connection
Dim oCmd As Command
Set oConn = New Connection
oConn.Open <your connection string goes here>
Set oCmd = New Command
oCmd.ActiveConnection = oConn
oCmd.CommandText = "INSERT INTO TableName (ColumnName) VALUES('string')"
oCmd.Execute
I don't have the ADO parameter syntax at hand, but you should be able to insert general strings (including NULs) into varchar columns using ADO Parameters.

SQL Server text column affects results returned to classic ASP

Using classic asp, I am trying to query a SQL Server database like so:
strSQL = "select column_1, column_2, column_3, column_4 from someview " &_
"where RecordNo=" & i
set rs=conn.Execute(strSQL)
if not rs.eof then
A = rs("column_1")
B = rs("column_2")
C = rs("column_3")
D = rs("column_4")
end if
Column_3 is an NText type, the other columns are varchar or int (sometimes there may be more than 4 columns returned) but the query only returns 1 record because of the where clause.
On the ASP page the results vary - sometimes A,B,D are populated, sometimes not - but all columns in the view contain data (when I query the SQL Server I see the expected results - all columns do contain data). If I remove column_3 which is NText from the strSQL everything works fine.
I've seen this behaviour on a couple other pages in the past. If I modify the ASP to get column_3 separately:
strSQL = "select column_3 from someview where RecordNo=" & i
The NText data is returned correctly.
Is there a maximum record length to a SQL Server recordset returned to classic ASP? Apart from splitting out the NTEXT into a separate query, is there anything else I can do?
EDIT: It just occured to me to try changing the connection string - inspired by this comment on a similar problem - the connection is via SQL Server ODBC Driver (Driver={SQL Server};).
I have had this problem. Microsoft acknowledge it somewhere on their website.
If you put the NText column last in the SELECT list, you will be able to access it ok.
However, your code cannot access any other columns after it has read the NText value. Once you move to the next row of the recordset you're OK again.
Best solution is to change your connection string though, and use something more modern. That solves the problem in the best way!
To avoid using the recordset, try this:
For 1 record returned:
arr = rs.Getrows
if IsArray(arr) then
A = arr(0)
B = arr(1)
C = arr(2)
D = arr(3)
end if
For more records:
aryList = rec.GetRows
iCount = Ubound(aryList,2)
For i = 0 to iCount
A = aryList(0,i)
B = aryList(1,i)
C = aryList(2,i)
D = aryList(3,i)
' Do something with A,B,C,D
Next
casting ntext to varchar will do the job.
You're mixing unicode data (the ntext column) with non-unicode (varchar). That may be the reason, since the ASP page has to decide which to use.
Try and use either one or the other (casting non-unicode data to unicode may be the better option).
One extra tip for those who are working with older code:
When a recordset's column value is blank using ADO/ASP and you have a single line of data, you can bypass this problem by using a parameterised Command statement and returning the string value into a variable:
Some hand-typed code hopefully explains what I mean:
' DB connection
Set objCon = Server.CreateObject("ADODB.Connection")
objCon.CursorLocation = adUseClient
objCon.Open pubDbConnString
' statement construction
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = objCon
cmd.CommandText = "SELECT ?=T.Column1, ?=T.Column2 From Table T WHERE ID=?"
cmd.CommandType = adCmdText
' add parameters
cmd.Parameters.Append cmd.CreateParameter("#column1Data", adVarChar, adParamOutput, 8000)
cmd.Parameters.Append cmd.CreateParameter("#column2Data", adTinyInt, adParamOutput)
cmd.Parameters.Append cmd.CreateParameter("#id", adBigInt, adParamInput)
cmd.Parameters("#id").value = 1
set objRS = cmd.Execute
#column1Data will contain the large string. objRS will actually not have any records in it, so be mindful of this.
In theory, this should also work with named parameters with the same results, but I have not tested this.

Resources