SQL Query not inputting value of my variable - asp.net

I'm having some trouble writing a query using variables. Here's my code
Dim bondnumber as String = "69836"
Dim PasswordCheck As String = "DECLARE #investor varchar(10),
#thepassword varchar(20), #linkedserver2 varchar(25), #sql varchar(1000) "
PasswordCheck += "SELECT #investor = '" & bondnumber & "',
#linkedserver2 = 'binfodev', "PasswordCheck += "#sql = 'SELECT * FROM ' +
#linkedserver2 + ' WHERE bondno = ''#investor'' ' EXEC(#sql)"
It doesn't seem to be passing the variables properly in the query and i'm not sure where i'm going wrong
any ideas?

What is the problem you are seeing specifically? More info would help.
What I can tell, is that you're code translates to a long line of SQL (substituting '69836' for bondnumber)
DECLARE #investor varchar(10), #thepassword varchar(20), #linkedserver2 varchar(25), #sql varchar(1000) SELECT #investor = '69836', #linkedserver2 = 'binfodev', #sql = 'SELECT * FROM ' + #linkedserver2 + ' WHERE bondno = ''#investor'' ' EXEC(#sql)
I'll bet if you execute that in a query window it will fail. Try adding ; at the end of each logical statement.
Have you considered just making this code a stored procedure and passing params to this? Code like this is pretty hazardous (SQL Injection), hard to read, and just a bit ugly in general.
Sample Stored Procedure Code:
CREATE PROCEDURE dbo.usp_MyStoredProcedure
#Param1 INT = NULL
AS
SELECT * FROM MyTable Where Col1 = #Param1

#Jamie - Well I personally tend to find it is much clearer to break things a part a little bit although its not technically necessary. I am just saying to build your parameter variables separately and then add them as parameterized (something like the following):
Dim sql As String = "SELECT * FROM #LinkedServer WHERE bondno = #BondNumber"
Dim c As New SqlConnection("Your Connection String Here")
Dim cmd As SqlCommand = c.CreateCommand()
With cmd
.CommandType = CommandType.Text
.CommandText = sql
.Parameters.Add(New SqlParameter("#LinkedServer", SqlDbType.VarChar)).Value = "binfodev"
.Parameters.Add(New SqlParameter("#BondNumber", SqlDbType.VarChar)).Value = "69836"
End With
Dim dt As New DataTable
Dim da As New SqlDataAdapter(cmd)
da.Fill(dt)

Related

Dynamic query as a parameter in stored procedure and SQL Injection

I have the following stored procedure (modified for this post):
ALTER PROCEDURE [dbo].[SEL_ARTICLE](
#FILTER VARCHAR(8000) = ''
) AS
BEGIN
DECLARE #SQLQuery varchar(8000);
SET #SQLQuery = 'SELECT DISTINCT ArticleNo, desc, ...
FROM Article INNER JOIN
...
{0}
ORDER BY ArticleNo, ...';
SET #SQLQuery = REPLACE(#SQLQuery, '{0}', #FILTER);
EXEC(#SQLQuery);
END
I call this proc in my prog like this:
Public Function get_Article(ByVal strFilter As String) As DataTable
Dim tblData As New DataTable
Dim par As SqlParameter = New SqlParameter("#FILTER", SqlDbType.VarChar)
par.Value = strFilter
Load_Data("SEL_ARTICLE", tblData, par) 'SqlCommand used
Return tblData
End Function
The value of the parameter strFilter is dynamic (Fields, values) depending on what we search. Here is an example:
" AND ((Article = [input from User]) OR (Description LIKE '%[input from User]%'))"
The user must be able to enter the character ' (word in French) it is why I replace it server-side like this:
strFilter &= String.Format(" AND ((Article = {0}) OR (description LIKE '%{1}%'))", strArticleNo, strArticleName.Replace("'", "''"))
I prevent the user to enter the following characters: <,>,{,},;
Now my question:
Is this code safe against SQL injection attacks ?
Thank you!

Update SQL Server tables using textboxes

I'm programming an education website using asp.net vb.net and SQL Server. I have 4 stackholders, if any body log in in his profile he will see his information
If he wants to update them he just change the textboxes then click update
My problem is how to update.
I wrote a method to update but it always show me a syntax error in the query. I made sure there is no problem. I'm updating two tables and I made to sql statements!
My qustion is can I Insert instead of update?
If not: how to upade one record based on the session I have?
please help me
this my code
' Private Sub UpdateInfo(ByVal USER_ID As Integer)
'Dim User As Integer = USER_ID
'Dim sql1 As String = "UPDATE AdminCoordinatorInformation SET MobileNumber =" + tbmobile.Text + ", HomeNumber=" + tbhome.Text + ", AltRelation = " + DDLRelationShip.SelectedValue + ", AlTitle = " + DDLTitle.SelectedValue + ", AltName = " + tbemname.Text + ", AltMobile = " + tbemmobile.Text + " WHERE USER_ID = User)"
'Dim sql2 As String = "UPDATE DIP_USERS SET USER_Email=" + tbEmail.Text.Trim + " WHERE USER_ID = User)"
' Try
' Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("mydbConnectionString").ConnectionString)
' Dim cmd1 As New SqlCommand(sql1, conn)
' Dim cmd2 As New SqlCommand(sql2, conn)
' cmd2.Parameters.AddWithValue("#FirstName", tbname.Text)
' cmd2.Parameters.AddWithValue("#USER_PASSWORD", tbnewpassword.Text)
' cmd2.Parameters.AddWithValue("#USER_Email", tbEmail.Text)
' cmd1.Parameters.AddWithValue("#MobileNumber", tbmobile.Text)
' cmd1.Parameters.AddWithValue("#HomeNumber", tbhome.Text)
' cmd1.Parameters.AddWithValue("#AltRelation", DDLRelationShip.SelectedValue)
' cmd1.Parameters.AddWithValue("#AlTitle", DDLTitle.SelectedValue)
' cmd1.Parameters.AddWithValue("#AltName", tbemname.Text)
' cmd1.Parameters.AddWithValue("#AltMobile", tbemmobile.Text)
' conn.Open()
'Dim ra As Integer = cmd1.ExecuteNonQuery()
'Dim ra1 As Integer = cmd2.ExecuteNonQuery()
'cmd1.Dispose()
'cmd2.Dispose()
' conn.Close()
' Catch ex As Exception
' MsgBox(ex.Message)
' End Try
'End Sub
you have not specified your parameters in your query, you're directly concatenating the values of controls inside your query. And still you have added parameters.
Firstly, do not concatenate your sql query like that, its prone to SQL Injection.
construct your query like this:
Dim sql1 As String = "UPDATE AdminCoordinatorInformation SET
MobileNumber =#MobileNumber,
HomeNumber=#HomeNumber,
AltRelation = #AltRelation,
AlTitle = #AlTitle,
AltName =#AltName,
AltMobile = #AltMobile
WHERE USER_ID = #User"
Dim sql2 As String = "UPDATE DIP_USERS SET
USER_Email=#USER_Email
WHERE USER_ID = #User"
and also, add this parameter too
cmd1.Parameters.AddWithValue("#User", USER_ID)
cmd2.Parameters.AddWithValue("#User", USER_ID)
And one very important thing. you need to assign proper datatype to your columns in the query i.e.
remember these things.
txtBox.Text returns String value, you might need to convert it to Int32 using Convert.Int32 or you need to wrap it in single quote, based totally upon datatype of your column
Put parameters which you declare in your SQL Command query:
"UPDATE AdminCoordinatorInformation SET MobileNumber=#MobileNumber,HomeNumber=#homeNumber...
You get syntax error because your string data in sql query must be wrapped with "'".
"UPDATE AdminCoordinatorInformation SET MobileNumber='0987654321',....
Note: creating sql queries by concating query with user inputs ("...SET MobileNumber='" + txtbox.Text + "',...") is not good/dangerous practice because of SQL Injection

Executing User Defined Function via Classic ASP Function

OK, I am trying to write a Classic ASP function that will call a SQL function and return the output.
I am trying to use a paramaterized ADODB connection but I don't quite know how these work. Trying to learn the correct way.
The SQL function just takes two string input where one is a "salt" and the other the actual text and turnes it into a hex.
Works fine in SQL but I just can not get it to work through classic ASP.
I keep getting,
ADODB.Command error '800a0cc1'
Item cannot be found in the collection corresponding to the requested name or ordinal.
Sub Encrypt(plainString)
strSQL = "SET NOCOUNT ON;SELECT dbo.Encrypt('xx', '?') as keycode"
Set cnnEncrypt = Server.CreateObject("ADODB.Connection")
cnnEncrypt.open CONNSTRING
Dim cmd1
Set cmd1 = Server.CreateObject("ADODB.Command")
cmd1.ActiveConnection = cnnEncrypt
cmd1.CommandText = strSQL
cmd1.CommandType = adCmdText
cmd1.Parameters(0) = plainString (**Original Error Occured Here!!!!**)
Set rsEncrypt = cmd1.Execute()
If not rsEncrypt.EOF Then
Encrypt = rsEncrypt.Fields("keycode").Value
Else
Encrypt = "blank"
End If
' Clean Up
rsEncrypt.Close
Set rsEncrypt = Nothing
cnnEncrypt.Close
Set cnnEncrypt = Nothing
End Sub
New Working Version after reviewing "Cheran Shunmugavel" answer.
Calling on site like this
< % Response.Write Decrypt(Encrypt("test")) % >
You can't print the Encrypted code to the page because it is Binary. You would need a Binary to String function.
I converted from Sub to Function because I wanted the function to return a value.
Function Encrypt(byVal plainString)
strSQL = "SET NOCOUNT ON;SELECT dbo.Encrypt('xx', ?) as keycode"
Set cnnEncrypt = Server.CreateObject("ADODB.Connection")
cnnEncrypt.open CONNSTRING
Dim cmd1
Set cmd1 = Server.CreateObject("ADODB.Command")
cmd1.ActiveConnection = cnnEncrypt
cmd1.CommandText = strSQL
cmd1.CommandType = adCmdText
cmd1.Parameters.Append cmd1.CreateParameter("", adVarChar, adParamInput, Len(plainString)+1, plainString)
Set rsEncrypt = cmd1.Execute()
If not rsEncrypt.EOF Then
Encrypt = rsEncrypt.Fields("keycode").Value
Else
Encrypt = "blank"
End If
' Clean Up
rsEncrypt.Close
Set rsEncrypt = Nothing
cnnEncrypt.Close
Set cnnEncrypt = Nothing
End Function
And here is the decrypt function.
Function Decrypt(byVal plainString)
strSQL = "SET NOCOUNT ON;SELECT dbo.Decrypt('xx', ?) as keycode"
Set cnnDecrypt = Server.CreateObject("ADODB.Connection")
cnnDecrypt.open CONNSTRING
Dim cmd1
Set cmd1 = Server.CreateObject("ADODB.Command")
cmd1.ActiveConnection = cnnDecrypt
cmd1.CommandText = strSQL
cmd1.CommandType = adCmdText
cmd1.Parameters.Append cmd1.CreateParameter("", adVarBinary, adParamInput, LenB(plainString)+1, plainString)
Set rsDecrypt = cmd1.Execute()
If not rsDecrypt.EOF Then
Decrypt = rsDecrypt.Fields("keycode").Value
Else
Decrypt = "blank"
End If
' Clean Up
rsDecrypt.Close
Set rsDecrypt = Nothing
cnnDecrypt.Close
Set cnnDecrypt = Nothing
End Function
First off, you don't need delimiters around the parameter placeholder. SQL Server will handle it appropriately.
strSQL = "SET NOCOUNT ON;SELECT dbo.Encrypt('xx', ?) as keycode"
Secondly, the Parameters collection is initially empty and must be populated before you try to access it (i.e., the line cmd1.Parameters(0) = plainString). There are several ways of doing this, but I prefer creating the parameters manually using the CreateParameter method:
cmd1.Parameters.Append cmd1.CreateParameter("", adVarChar, adParamInput, Len(plainString), plainString)
Also, it's not apparent from your code, but make sure you've got the ADO constants defined, either by referencing the type library, or by including adovbs.inc.

DataReader already open error when trying to run two queries

I have a couple of queries that I need to run one to a linked server and one not like this
Dim InvestorLookup As String = "DECLARE #investor varchar(10), #linkedserver varchar(25), #sql varchar(1000) "
InvestorLookup += "SELECT #investor = '" & investor & "', #linkedserver = '" & db & "', "
InvestorLookup += "#sql = 'SELECT * FROM OPENQUERY(' +#linkedserver + ', ''SELECT * FROM db WHERE investor = ' + #investor + ' '')' EXEC(#sql)"
Dim queryInvestorLookup As SqlCommand = New SqlCommand(InvestorLookup , conn)
Dim BondNoDR As SqlDataReader = queryInvestorLookup.ExecuteReader()
Dim PasswordCheck As String = "DECLARE #investor varchar(10), #password varchar(20), #linkedserver varchar(25), #sql varchar(1000) "
PasswordCheck += "SELECT #investor = '" + investor + "', #password = '" + password + "', #server = '" + db2 + "', "
PasswordCheck += "#sql = 'SELECT * FROM #server WHERE investor = #investor AND password = ' + #password + ' '' EXEC(#sql)"
Dim queryPasswordCheck As SqlCommand = New SqlCommand(PasswordCheck, conn)
Dim PasswordDR As SqlDataReader = queryPasswordCheck.ExecuteReader()
As far as I can tell from debugging the queries both run as they should but I get the error
There is already an open DataReader associated with this Command which must be closed first.
Is it possible to run two queries in two different DataReaders. I need to later reference each DataReader and select values from each.
By default it´s not possible to have two SqlDataReader's open at the same time sharing the same SqlConnection object. You should close the first one (queryInvestorLookup) before calling the second (queryPasswordCheck).
This would be good from a design and performance point of view since a recommendation for .NET is that every unmanaged resource (like database access) is opened as later as possible and closed early as possible.
Another way would be to enable MARS but afaik it is only available for Sql2005 and up.
The third solution would be to use the same SqlDataReader to issue the two queries and then navigate through then using NextResults() method.
If the provider that you are using supports it, you can enable MARS (Multiple Active Result Sets) by adding MultipleActiveResultSets=True to the connection string that you are using.
By default you can't have to dataReaders open on the same connection. So you could get one result, stuff it in a DataTable and then get the other result. Or you could turn on MARS
ADO.NET Multiple Active Resut Sets

Parameterized query - error when executing a query

I've recently been trying to figure out a way to get parameterized queries to work and i think i'm almost there but seem to be getting an error when executing my query
Here's the code
Dim LogData2 As sterm.MarkData = New sterm.MarkData()
Dim query As String = ("Select * from openquery (db, 'SELECT * FROM table WHERE investor=#investor')")
Dim cmd As New SqlCommand(query)
cmd.Parameters.AddWithValue("#investor", 34)
Dim drCode2a As DataSet = LogData2.StermQ3(query)
I've debugged it and it doesn't seem to be putting the parameter into the query.
"Select * from openquery (db, 'SELECT * FROM table WHERE investor=#investor')"
That's what i get when i debug the line Dim drCode2a As DataSet = LogData2.StermQ3(query)
Any ideas what i'm doing wrong?
SOLUTION
Here's how I solved my problem
Dim conn As SqlConnection = New SqlConnection("server='h'; user id='w'; password='w'; database='w'; pooling='false'")
conn.Open()
Dim query As New SqlCommand("DECLARE #investor varchar(10), #sql varchar(1000) Select #investor = 69836 select #sql = 'SELECT * FROM OPENQUERY(db,''SELECT * FROM table WHERE investor = ''''' + #investor + ''''''')' EXEC(#sql)", conn)
dgBookings.DataSource = query.ExecuteReader
dgBookings.DataBind()
Thanks for the help
Ok Jamie taylor I will try to answer your question again.
You are using OpenQuery becuase you are probably using a linked DB
Basically the problem is the OpenQuery Method takes a string you cannot pass a variable as part of the string you sent to OpenQuery.
You can format your query like this instead. The notation follows servername.databasename.schemaname.tablename. If you are using a linked server via odbc then omit databasename and schemaname, as illustrated below
Dim conn As SqlConnection = New SqlConnection("your SQL Connection String")
Dim cmd As SqlCommand = conn.CreateCommand()
cmd.CommandText = "Select * db...table where investor = #investor"
Dim parameter As SqlParameter = cmd.CreateParameter()
parameter.DbType = SqlDbType.Int
parameter.ParameterName = "#investor"
parameter.Direction = ParameterDirection.Input
parameter.Value = 34

Resources