how to add wild card? - asp.net

Hi i am new programmer asp.net and vb.net. I wanted using wild card to search engine.
i am puzzled put wild card (%).
Protected Sub search()
Dim ds As New DataSet
Dim cls As New Class1
ds = cls.returndataset("select * from student where Nama_Depan like '" & nama.Text & "' ")
viewatt.DataSource = ds
viewatt.DataBind()
End Sub
Thanks in advance for any help, and I'm really sorry if this has been asked before.

As others have already pointed out
select * from student where Nama_Depan like '%" & nama.Text & "%'
is the correct way to use wildcards
Here is a link to the W3Schools tutorial on SQL wildcards: http://www.w3schools.com/sql/sql_wildcards.asp
I would suggest you have a quick read through, the W3schools articles are usually really good.
This however is a really bad way to execute SQL commands from your code, someone could quite easily inject some SQL code into your textbox and when your query is executed it could destroy your database.
As an exaple if someone entered '; DROP TABLE * -- into your textbox, this would allow your first query to run, then it would drop all your tables.
It is really easy to get around this by using parameterised queries or stored procedures. Personally I would favour using Stored Procedured and you can do so like this.
CREATE PROCEDURE MyProc
(
#param1 VARCHAR(50)
)
AS
BEGIN
select * from student where Nama_Depan like '%"'+#param1+'%'
END
You would then just need to edit your VB code to call the stored procedure rather than executing the SQL command.
The other advantage of using a stored procedure is that they perform slightly faster and are more efficient, this is because when you pass some SQL to the database it has to compile it into a sql command to execute, stored procedures are already stored on the database and so do not need to do this.
There are also some added security benefits to using a stored procedure rather than just transmitting a SQL statement, If anyone were to intercept your SQL statement on its way across the network / internet they could gain some insight into your database structure. With a stored procedure all they could possibly intercept is the procedure name and some parameters.

Try this.
Protected Sub search()
Dim ds As New DataSet
Dim cls As New Class1
ds = cls.returndataset("select * from student where Nama_Depan like '%" & nama.Text & "%' ")
viewatt.DataSource = ds
viewatt.DataBind()
End Sub

Related

Trying to understand how ASP.NET .XSL gets/saves data to/from a database

This is probably a old topic. I have an older ASP.NET application that I'm charged with modifying. I've not used this technology before. I see in the .xls files, things like <xls:value-of select="..." /> which seems to return values from the database.
I've done some searching but keep coming up with nothing relevant. Prolly because I'm using the wrong search strings. I have access to the database and the .xsl files but there's no .xml files or .xslt files in the project that I have (no project files either for that matter). Other than "<xls:value-of... />", I've no idea how the data in the database gets to the web page. Any help is appreciated.
not really sure what to suggest here. This suggests that the dataset designer was used. How this works is REALLY very much like EF (entity frameworks). The dataset designer is a typical ORM (Object relational management system).
In fact, using the dataset designer is VERY much like using EF.
However, the dataset designer does NOT let you set/use a database connection string.
(you choose one WHEN creating the dataset). But you no doubt have a defined connection anyway. If you change that connection string, then the dataset designers will now use that changed connection string anyway.
Like EF? Well, do you really care much how it works, or do you just care that you have the tables as some data model? I tend to not care anything more then
Hey, do I have a table - can I use it? can I feed the results to say a gridview or some such? So in effect, what you REALLY care about is how to use those data objects in code.
So, then you don't care if the database is Oracle, MySQL, SQL server, or even MS-Access.
When you open/launch say a xsd file in vs? the dataset desinger should launch.
So, You see this:
So, the above is 100% the SAME regardless of the actaual database being used. As noted, it could be MS-Access or Oracle - I don't care. In BOTH cases or in fact regadless of the database enigne, I will STILL get the above, and NOT have to change my code or care about the database in question.
So, we can for example write out in code to fill a grid view. (that's what we often call database first, or simply that we don't use EF, or the older datasets - which I noted are the same idea).
So, say I drop a grid view onto a page.
So, to fill the Grid, I might have this
(just code - no EF or Dataset designer used).
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid
End If
End Sub
Sub LoadGrid()
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String =
"SELECT TOP 10 FirstName, LastName, HotelName, City, Description
FROM tblHotels ORDER BY HotelName"
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
GridView1.DataSource = cmdSQL.ExecuteReader
GridView1.DataBind()
End Using
End Using
End Sub
And now I have this:
But, in place of typing in specific sql server syntax, and building that data table in code?
I would consider using EF or the older dataset designer.
so, I can add a new query in the dataset designer.
So, now we have a really nice "central" means to see our database schema, and a nice central place to say add queries and manage the data model.
This means I don't have in-line SQL tossed around in the code base like spaghetti.
So adding store procedure methods (with parameters), general queries, and a REALLY nice 50,000 foot view of the data model is why we use EF , or the older dataset designer. This so called ORM approach is common used.
So, now the above code, say based on my dataset, and that query I added to/in the dataset designer? I can now use that one query over and over in code.
I added the new query and called it GetMyHotels
So, now my code to fill the grid view becomes this:
Dim Mydt As New TEST4TableAdapters.tblHotelsTableAdapter
GridView1.DataSource = Mydt.GetMyHotels
GridView1.DataBind()
And I even get intel-sense for "GetMyHotels"
So, you don't now mess with SQL or even connection strings in code. You have a "object" that is your database.

Stored Procedure from SQL Server is not filling ASP.Net dropdown using VB.Net coding

Situation:
I have a pre-built form that uses two Form Views. One is for pickup and one for delivery. The form can't be changed due to client requirements. The entire form and Form Views use a WizardStep process.
Each side pre-fills in the clients company name and related data such as Pickup Name, address, city, state etc as well as Delivery Info all using the same fields using the same stored procedure.
The stored procedure shows the concat of Name and Address 1 as FullName and the ClientSubCtr. ClientSubCtr is an int field. This id is what populates the correct data to each dropdown.
The dropdown list is not inside the FormView and falls under the form tag.
When testing the connection via the <asp:SqlDataSource> tag everything works in the Configure Data Source and data is returned using the appropriate parameter. The connection for the matching client data uses a basic Select to the table used in the stored procedure. I've tried to use a different stored procedure for the data, but no success there either. I am using SQL Server Express right now locally.
I've tried disabling the asp:SqlDataSource and just use a database connection from page_load, which did not work. I've commented it out as I'm still trying different things. I may be missing some syntax to connect to the dropdown here.
'This did not work
'Using conn As New SqlConnection(connect)
' strSQL = "SELECT ClientSubCtr,CONCAT(Name,Address1) AS FullName 'FROM tblClientsSub"
' strSQL = strSQL & " WHERE Account ='" & sessAccount & "'"
' strSQL = strSQL & " ORDER BY FullName ASC"
' conn.Open()
' Using cmd As New SqlCommand(strSQL, conn)
' cmd.Parameters.AddWithValue("#Account", sessAccount)
' cmd.CommandText = strSQL
' cmd.ExecuteNonQuery()
' Dim dr As SqlDataReader = cmd.ExecuteReader()
' If dr.HasRows Then
' Do While (dr.Read())
' ClientSubCtr = dr.GetValue(0)
' FullName = dr.GetValue(1)
' s1_cboAcct.DataTextField = FullName
' s1_cboAcct.DataValueField = ClientSubCtr
' s1_cboAcct.DataBind()
'Corrected Databind still does not work
' Loop
' Else
' dr.Close()
' End If
' End Using
'End Using
Additional info: Prior to using this I have two Pre-Render functions. One for Pickup and Delivery which fills in what my client calls a Docket. It shows the info that was pre-filled in with the initial loading or by the Selected Change on the dropdown and or where the client manually added or changed something, thus sending the correct information to the database for eventual download.
Note: This was originally written making OLEDB ACE connections to my clients Go Daddy account. Go Daddy moved the site to a new server and will no longer support ACE 12.0. We begged for them to change this. Thus, the move to SQL Server.
When I get what I believe is the data getting load I get an error in my pre-render on this tag. I've purposely commented out all the pre-render to see what was returned in regards to errors. No errors are return and the general form returns showing the drop-down but no data and the field in the FormView can't be seen. In other words not even the labels are showing. I've checked all asp:sqldatasource settings.
' If IsNothing("txtcboAcct.Text") Then
'lblDocketPUName.Text = ""
(I've tried using Request.form here, but data isn't loaded so I get nothing.) and commented out the If Else End If
' Else
' lblDocketPUName.Text = CType(frmViewPUClient.FindControl("txtcboAcct"), TextBox).Text
(This is where I get an error where the object is not found because neither the data for the dropdown is loading or the data for the forms.)
' End If
I know this is a lot to digest, but I'm totally baffled why this works perfectly using OLEDB and Access 2007 but when switching to SQL Server and the exact tables named the same, it does not. Any insight to why the stored procedure won't fill in the dropdown or why even my code in page_load wouldn't fill in the drop-down would be helpful. I've updated all parameters to use the # symbol.
Here is the stored procedure:
'ALTER PROCEDURE [dbo].[qryFullNameAddr]
'#Account nvarchar(10) OUTPUT
'AS
' -- Add the parameters for the stored procedure here
'DECLARE #ClientSubCtr int
'DECLARE #Name nvarchar(50)
'DECLARE #Address1 nvarchar(125)
'DECLARE #FullName nvarchar(255)
'BEGIN
' -- SET NOCOUNT ON added to prevent extra result sets from
' -- interfering with SELECT statements.
' SET NOCOUNT ON;
' /*Write statements for procedure here */
'SELECT ClientSubCtr,CONCAT(Name,Address1) AS FullName
'FROM tblClientsSub
'WHERE #Account=#Account
'ORDER BY FULLNAME, ADDRESS1 ASC
'end
Well, first I would back the truck up so to speak.
I would create a blank new test web page. Put in a dropdown list, and get it working.
Next up:
You don't need to loop for a drop down list. You can feed a dropdown a TABLE. And that table can be a query, or perhaps a stored procedure.
So, for starters, lets display a Hotel List in a drop down. And like most drop downs, there are often two columns the hidden "id" or often "PK" of the row, and then the display text.
So, our blank we page, we drop in a drop down list. Say like this:
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="DropDownList1" runat="server"
DataTextField="HotelName"
DataValueField="ID" Height="22px" Width="219px">
</asp:DropDownList>
</div>
</form>
And now the code to fill - and as noted ALWAYS ALWAYS load only on first page load - that is PostBack = false - (break that rule, and you can't really even make a correctly working web page).
Ok, so our code is now this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData
End If
End Sub
Sub LoadData()
Using con As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String = "SELECT ID, HotelName from tblHotels ORDER BY HotelName"
Using cmdSQL As SqlCommand = New SqlCommand(strSQL, con)
con.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
DropDownList1.DataSource = rstData
DropDownList1.DataBind()
DropDownList1.Items.Insert(0, New ListItem("", "")) ' optional blank starting select
End Using
End Using
End Sub
That's it!!!
Also, don't know why so many code examples set the DataTextField and DataValue field in code? Why???? Just use the property sheet - little need to put such things in the code side - ESPECIALLY when the property sheet can do that for you!!!
Next up? Well, everyone always on SO piles in about how you should use parameters in such code in place of concatemer strings. This is correct, but if you code with parameters, then you can OFTEN reduce code, and CLEAN UP your sql anyway.
In place of say a messy sql string, you remove the text ('quotes'), and numbers (no quotes), and this even works better for dates.
So this benefit is near as great as the issue of sql injection issues.
(and to be fair, you noted a stored procedure, and it not working, so clearly you decided to try anything here - I get that approach).
So, your code snip? I would code it this way:
Dim strSQL As String =
"SELECT ClientSubCtr,CONCAT(Name, Address1) AS FullName FROM tblClientsSub " &
"WHERE Account = #Acc " &
"ORDER BY FullName ASC"
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(strSQL, conn)
cmdSQL.Parameters.Add("#Acc", SqlDbType.NVarChar).Value = sessAccount
conn.Open()
s1_cboAcct.DataSource = cmdSQL.ExecuteReader
s1_cboAcct.DataBind()
End Using
End Using
Now is that not MUCH more readable?
And in fact cut + paste your code?
I noticed this:
SELECT ClientSubCtr,CONCAT(Name,Address1) AS FullName 'FROM
Wait? what is the ' right before the FROM???? You have a stray ', don't you?
Maybe that was a code cut + paste error, maybe not. But the REAL POINT?
By using parmaters we go nuclear on the single, double quotes, and all that jazz.
in other words, sure, avoiding string concntatiion of values is important for reasons of sql injection, but REALLY MUCH more valuable is how we don't have to bother with all those quotes and stuff. The result is it is MUCH HARDER to miss or mess up!!!
The other issue of course is by using the parameters as per above?
Well, we get intel-sense. And if I have several more, then in VS I just hit ctrl-d to dupplie the line. I actually wind up TYPING LESS code then If I attempted to introduce those values right into the sql!!! Imagine that - eaiser to read, and even less typing of code!!! - all this amounts up to much less error prone code. I mean, one missing quote like ' or a extra one? You in trouble and will waste time!!
You ALSO note that I did not even use a reader into a DataTable, and just shoved the reader results RIGHT into the combo box - saves even more code!!!!
However, while a dropdown, listview, gridview (and many more) can ALL accept DataSource as a cmdSQL.ExecuteReader as I did?
I still STRONG recommend you use my first version for Grids/list views etc. (and a HUGE reason exists for this!!!). (data pagers don't work if you feed a gridview a reader, but a table they work fine, and also the data bind events (not often used for combo box, but VERY often used for grids often needs the data source - so for this combo? Sure you can skimp out on the two extra lines of code (to create a DataTable and load it). But for a gridview, don't use that cool short cut I used above by feeding the reader directly into grids or listviews - but for combos, perfect fine.
So, with above, and after running above code, we have this:
As noted, if you DO test or decide to load up a combo box, and NOT use say a DataSoruce control dropped into the markup (I don't like those things all that much), then MAKE SURE you put and ONLY call the loading of such controls inside the If Not IsPostBack code stub. DO NOT EVER fail to follow this rule.
Again: do NOT EVER EVER fail to follow this rule.
Why?
Becuase any other button or any other thing you EVER will place on that page may well need to do a post-back (say even a few simple buttons). So, if you say select a combo box, fill out some other things, and have some button (and a button click event with code behind)?
Wel, keep in mind that page load ALWAYS FIRES each post-back!!!!
So, if your code re-loads say the combo box, then it going to blow out any existing selecting the user has for that combo (or grid or just about anything else!!!). So, you have to write your code in a way that it will "assume" and "work" and "survive" post-backs. So your loading up of controls thus should only be ONE time, and on the first page load - hence my HUGE LONG narrative of how vast important it is to follow this simple rule.

How can I make a prepared statement in classic asp that prevents sql injection?

I have this which works:
sqlString = "SELECT * FROM employees WHERE lastname = '" & last_name & "'"
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = dbConn
cmd.CommandText = sqlString
cmd.Prepared = True
Set recs = cmd.Execute
The problem I have is that above the dynamic part of sqlString is before the prepared statement command. I don't think what I have above is protecting me.
Don't I have to fix this sqlString before I do the prepared statement? Reading this made me think that: How can prepared statements protect from SQL injection attacks?:
"While in case of prepared statements we don't alter our program, it remains intact
That's the point.
We are sending program to the server first
$db->prepare("SELECT * FROM users where id=?");
where the data is substituted by some variable called "placeholder"
and then we're sending the data separately:
$db->execute($data);
so, it can't alter our program and do any harm.
Quite simple - isn't it?"
But I don't know how to make my query correct. I also don't know how he got from prepare to $data. Was hoping for guidance. Thanks.
Why not use ADO command parameters?
var oCmd = Server.CreateObject("ADODB.Command");
oCmd.CommandText = "SELECT * FROM employees WHERE lastname = ?";
oCmd.Parameters.Append(oCmd.CreateParameter(undefined,202, 1, 50,"last name"))//adVarWChar
Here's a good blog on how to prevent sql injection using classic asp.
http://blogs.iis.net/nazim/archive/2008/04/28/filtering-sql-injection-from-classic-asp.aspx
The easiest is using stored procedures in SQL and using Commands that way.. Otherwise, you have to escape out certain characters being gathered from the Request object, like single quotes and double hyphens, etc.

Integer variable is acquiring a string value of "ad" somewhere along the line, can anyone see where?

Here is my code:
I should get output of the department id (did) as an integer and the templatefilename (result) that is required.
The errors I get are: Conversion from string "ad" to type 'Integer' is not valid. I'm fairly new to asp.net and cannot see where the did variable picks up the "ad" string.
Any help would be greatly appreciated.
Thanks
When you construct the query to the table departmentsgroupings, you're changing the value of sql, but you aren't creating a new SqlCommand. This means that cmd still contains the old SQL statement (the query to the Modules table) which, when executed, returns "ad".
To fix this, change your code as follows:
sql = ("select departmentsid from departmentsgroupings where groupingid =" & pageid & "")
Set cmd = New SqlCommand(sql, conn)
did = (cmd.ExecuteScalar)
You may have expected the change you made to sql to get passed on automatically to the SqlCommand -- but it doesn't work that way.
Edit: Your code, as written, is vulnerable to SQL injection attacks. If you don't know what these are, you need to read the first answer to this:
How does the SQL injection from the "Bobby Tables" XKCD comic work?
To protect yourself against these kinds of attacks, use parameterized queries.
The mistake is in these lines:
sql = ("select departmentsid from departmentsgroupings where groupingid =" & pageid & "")
did = (cmd.ExecuteScalar) <---- Wrong command executed here.
You presumably meant to execute the code in sql, not cmd again.

Constructing a good search query using system.data.oracleclient

I am constructing a search function in a class to be used by several of our asp pages. The idea is simple, take a search term from the user and query the database for the item. Currently I am doing this the wrong way, which is vulnerable to SQL injection attacks (and ELMAH is in there to save the day if something goes wrong):
Public Shared Function SearchByName(ByVal searchterm As String) As DataTable
SearchByName = New DataTable
Dim con As New OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings("OracleDB").ConnectionString)
Try
con.Open()
Dim SqlStr As String = "select ID_ELEMENT, ELEMENT_NAME from table_of_elements where upper(ELEMENT_NAME) like upper('%" & searchterm & "%')"
Dim cmd As New OracleCommand(SqlStr, con)
SearchByName.Load(cmd.ExecuteReader)
Catch ex As Exception
Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
End Try
con.Close()
con.Dispose()
Return SearchByName
End Function
String concatenation is BAD. Next thing you know, Bobby Tables wrecks my system.
Now, the correct way to do this is to to make a proper oracle variable, by putting :searchterm in the string and adding the following line:
cmd.Parameters.Add(New OracleParameter("SEARCHTERM", searchterm))
The problem is since I am using a like statement, I need to be able to have % on either side of the search word, and I can't seem to do that with '%:searchterm%', it just gives an error of ORA-01036: illegal variable name/number.
Can I parameterize but still have my flexible like statement be a part of it?
Instead of doing the concatenation in your VB code, do the concatenation in the SQL statement. Then what you're trying to do should work. Here's some SQL illustrating what I'm talking about:
select ID_ELEMENT, ELEMENT_NAME
from table_of_elements
where upper(ELEMENT_NAME) like ('%' || upper(:searchterm) || '%')
BTW, you might end up with more efficient queries if you switch the collation on ELEMENT_NAME to case-insensitive and then remove the calls to upper().
Since you're using oracle, another option would be to use Oracle Text to perform the search.
It can take a bit to set up properly, but if you have a large amount of text to search, or have some sort of structured data, it can offer you many more options than a simple wild-card comparison.
It also has some nice features for dealing with multiple languages, if you happen to have that problem as well.

Resources