tags:

views:

152

answers:

2

I'm a sql noob trying to get this query to use 2 tables.

tables & columns are:

person: department_id, name, etc...

department: department_id, dept_name, etc...

I have a 'select' html form that the user will choose a dept_name from, and I need my php script to return every person with a matching department_id. Here is my code & query so far, I'd appeciate any help.


$search_dept = $_POST['search_dept'];

$conn = odbc_connect($odbc_name, $user_name, $pass_wd);

if ($conn) {
    $query = "SELECT person.* 
                  FROM department 
                  JOIN person 
                  ON department.department_id=person.department_id 
                  WHERE department.name=$search_dept";

    if($result = odbc_exec($conn, $query)) {

     echo '..stuff';
     while ($row = odbc_fetch_array($result)) {
      ...echo stuff
     }
     echo '...stuff';
    }

    else {
     echo 'Query was unsuccessful';
    }
}

else {
    echo 'Unable to connect to database';
}
+2  A: 

Try this query, also make sure to escape any user input. What if the user would provide:

$_POST['search_dept']= "'; DROP TABLE person;";

Never ever ever thrust userinput!

$search_dept = mysql_escape_string($_POST['search_dept']); //make sure to escape this! you can use other functions for this as well. I'm not sure if PDO has some.
$query = "SELECT * 
              FROM person 
              JOIN department 
              ON department.department_id=person.department_id 
              WHERE department.name='$search_dept'";
Pim Jager
it is an odbc from a SQL SERVER DB...is there an escape function for that, or can I still use the mysql_escape_string()?
W_P
It's the single quotes in Pim's answer that are the major difference in the query here. Make sure you put single quotes around VARCHAR/TEXT string-esque types when writing SQL queries.
sheepsimulator
Or even better, use a parameterized query if that's possible. I'm not a php developer, but I would hope that would be possible.
Tom H.
@Tom H.: It depends on which set of functions you're using with PHP... also, depending on the PHP settings (magic_quotes_gpc specifically), PHP may already be escaping certain characters... this is going away in PHP6, though, as it causes more problems than it fixes.
R. Bemrose
@Tom H.: I just looked, there are odbc_prepare and odbc_execute functions to work with parameterized queries (see: http://www.php.net/odbc_prepare )
R. Bemrose
mysql_[real_]escape_string is only for MySQL, other databases have different escaping rules. SQL Server uses the ANSI standard quote-doubling ‘''’ instead of backslashing ‘\'’ which is the default in MySQL. You have to use a escape that matches your DBMS; of course parameterised queries are best.
bobince
mysql_escape_string() was just an example.
Pim Jager
mysql_real_escape_string() is the right answer. Both suck though and you should use parametrized queries.
Cory R. King
Don't you need a active mysql_ connection for mysql_real_escape_string to work?
Pim Jager
good question. dunno. I've always used mysql_real_escape_string, well, until they come up with mysql_we_really_mean_real_this_time_escape_string().
Cory R. King
+4  A: 

First of all, you are going about this the wrong way. You don't want to execute a WHERE clause against a text-type column if you can avoid it. Since your person table already has the department_id as a foreign key, you will want to use that value to do your selection. This means you will have to modify your select element to contain the department IDs as the options' values.

<!-- Example -->
<select name="dept_id">
    <option value="1">Sales</option>
    <option value="2">Support</option>
    <option value="3">Fulfillment</option>
</select>

So now, not only will just the raw selection occur faster since you'll be executing against an indexed column (you did make it a proper FK so it's indexed, right?), but you will also be removing the join altogether! (which is another boost to the query's speed)

// Here is injection-safe code for the ODBC driver
$stmt = odbc_prepare( "SELECT * FROM person WHERE department_id = ?" );
$success = odbc_execute( $stmt, array( $_POST['dept_id'] ) );

// Here is the old, non-secure version, but is db-driver agnostic
$deptId = $_POST['dept_id']; // escape this please!
$query = "SELECT * FROM person WHERE department_id = $deptId";
Peter Bailey
I am not a DB admin, so I can't change anything about the DB properties...I'm just a code monkey trying to make this website work with the db...but I like your solution...
W_P
This doesn't require you to change the DB, but it would require you to change the HTML select element.
Peter Bailey
k i got it...thanks!
W_P
you need to edit this "accpeted answer" to use mysql_real_escape_string(). people are gonna copy and paste this answer somewhere--too many PHP examples are insecure and this answer is no exception.
Cory R. King
I find it laughable that an example so specific to this person's problem (who's using ODBC btw) would be copied. It is not my personal responsibility to protect every wanton PHP developer from committing SQL injection. And if you down-voted my answer for this triviality, I find that very rude.
Peter Bailey
It is certainly not trivial and yes I did down-vote your answer. PHP is rife with poor examples which directly lead to the justifiably bad rap PHP gets with security. The code you give is yet another piece of insecure rubbish that now pollutes the internet.
Cory R. King
Look at my answer history for PHP questions and tell me you really think I'm doing PHP a disservice. Although I try, I don't always have the time to solve every secondary, tertiary and beyond problem with code snippets that are posted here. And for the record, I did edit my "rubbish" yesterday.
Peter Bailey