tags:

views:

193

answers:

5

Can someone let me know what is wrong with my SQL Statement and how I can improve it?

da = new SqlDataAdapter("SELECT * FROM Guests"+" WHERE Students.name='" + 
   byNametextBox.Text + "'", MyConn);
A: 
SqlDataAdapter("SELECT Guests.* FROM Guests,Students WHERE Guest.StudentId = Student.Id and  Students.name='" + byNametextBox.Text + "'", MyConn);`
tekBlues
thanks alot for you
What about SQL Injection?
George Stocker
A: 

You need an Inner Join. I think it would be something like this:

SELECT Guests.* FROM Guests INNER JOIN Students ON Students.name = Guests.name WHERE Students.name = '" + byNametextBox.Text + "'"
Matthew Jones
+1 upvoted for inner join.
p.campbell
What happens if my name is ';DROP TABLE Guests--?
LukeH
Little Bobby Tables is what happens. http://xkcd.com/327/
George Stocker
What about SQL Injection?
George Stocker
A: 

Try it:

"SELECT g.*
FROM Guests g
INNER JOIN Students s ON g.StudentId = s.StudentId
WHERE Students.Name = '" + byNametextBox.Text + '"'

Assuming that the field wich relates both tables is StudentId.

Beware that SQL is not the same between different Servers. This statement will work on Sql Server, I don't know in others. Also, beware that you aren't protecting yourself on SQL Injection attacks. You should perform your query with parameters, instead of concatenating strings in the way you are doing it.

This is a simple query that you should know by yourself. You can search for tutorials on Google, but here is a generic introduction.

eKek0
Can you use a SQLDataAdapter for anything other than SQL Server?
Jeff O
@Guiness: The Sql* objects (including SqlDataAdapter) in the System.Data.SqlClient are for use with SQL Server only. More generic objects of similar names exist in the System.Data.OleDb and System.Data.Odbc namespaces (e.g. OleDbDataAdapter, and OdbcDataAdapter) allow you to use the same functionality with any database you have an OLEDB provider or ODBC driver for. Other DB vendors may provide their own assemblies that provide similar functionality.
Jason Musgrove
I wouldn't show him a 'wrong' way of doing it. Show the right way. Someone may come along and use your code without understanding what SQL Injection is.
George Stocker
+4  A: 

An EXISTS predicate is slightly more efficient than a JOIN if you want only columns from one of the tables. Additionaly - never inject strings into SQL statements like that - you're just begging for SQL Injection attacks, or related crashes errors (Yes, I know it's a Forms application, but the same holds true. If you're searching for a name like "O'Leary", you'll get a crash).

SqlCommand cmd = new SqlCommand("SELECT * FROM Guests WHERE EXISTS (SELECT Id FROM Students WHERE Guests.StudentId = Students.Id And Students.name= @name)", MyConn);
cmd.Parameters.Add("@name", SqlDbType.VarChar, 50).Value = byNametextBox.Text;
SqlDataAdapter adapt = new SqlDataAdapter(cmd);

Note: Some people may argue that "SELECT *" is bad, and that you should consider specifying individual column names

Jason Musgrove
+1 for using parameters.
Paulo Santos
+1  A: 

You need to worry about SQL Injection. Put simply, SQL Injection is when a user is able to put arbitrary SQL statements into your query. To get around this, either use a Stored Procedure or a Parametrized SQL Query. An Example of a Parametrized SQL query is below:

SqlConnection conn   = null;
SqlDataReader reader = null;
//Connection string goes here

string studentName = byNametextBox.Text;

SqlCommand cmd = new SqlCommand(
 "SELECT * FROM Guests "+" WHERE Students.name = @name", conn);

SqlParameter param  = new SqlParameter("@name", SqlDbType.NVarChar, 50);

param.Value = studentName;

cmd.Parameters.Add(param);
reader = cmd.ExecuteReader();
//Do stuff with reader here
George Stocker
+1 for using parametrized query! That's the way all queries ought to be....
marc_s