I'm creating a search box that queries two MySQL tables and lists the results in real time. For now though, I have a working prototype that will query only one table. I've written the following PHP code in conjunction with JQuery and it works wonderfully:
HTML
<input onkeyup="search(this);" type="text">
<ol id="search-results-container"></ol>
Javascript
function search(input) {
var inputQuery = input.value;
/* $() creates a JQuery selector object, so we can use its html() method */
var resultsList = $(document.getElementById("search-results-container"));
//Check if string is empty
if (inputQuery.length > 0) {
$.get("search-query.php", {query: inputQuery}).done(function(data) {
//Show results in HTML document
resultsList.html(data);
});
}
else { //String query is empty
resultList.empty();
}
}
and PHP
<?php
include("config.php"); //database link
if(isset($_REQUEST["query"])) {
$sql = "SELECT * FROM students WHERE lastname LIKE ? LIMIT 5";
/* Creates $stmt and checks if mysqli_prepare is true */
if ($stmt = mysqli_prepare($link, $sql)) {
//Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_query);
//set parameters
$param_query = $_REQUEST["query"] . '%';
//Try and execute the prepared statement
if (mysqli_stmt_execute($stmt)) {
$result = mysqli_stmt_get_result($stmt);
//get number of rows
$count = mysqli_num_rows($result);
if ($count > 0) {
//Fetch result rows as assoc array
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
echo "<h1>Students:</h1>"; //Header indicates student list
for ($i = 0; $i < $count; $i++) {
$name = $row["lastname"];
echo "<p>$name</p>";
}
}
else { //Count == 0
echo "No matches found.<br>";
}
}
else { //Execution of preped statement failed.
echo "Could not execute MySQL query.<br>";
}
} // end mysqli_prepare
} // end $_RESQUEST isset
?>
The details of the students table are arbitrary, except for the fact that it has a String column that lists the student's last name.
My problem is that there is also a staff table which is effectively the same as students but for a different purpose. I'd like to query the staff table at the same time as students, but have the results separated like so:
<h1>Students:</h1>
<p>Student1</p>
<p>Student2</p>
<h1>Staff</h1>
<p>Staff1</p>
<p>Staff2</p>
The obvious answer would be to add another $sql statement similar to the one on Line 5 and just do both queries serially - effectively doubling the search time - but I'm concerned this will take too long. Is this a false assumption (that there will be a noticeable time difference), or is there actually a way to do both queries alongside each other? Thanks in advance!
If the two tables have identical structures, or if there is a subset of columns which could be made to be the same, then a UNION query might work here:
SELECT *, 0 AS type FROM students WHERE lastname LIKE ?
UNION ALL
SELECT *, 1 FROM staff WHERE lastname LIKE ?
ORDER BY type;
I removed the LIMIT clause because you don't have an ORDER BY clause, which makes using LIMIT fairly meaningless.
Note that I introduced a computed column type which the result set, when ordered by it, would place students before staff. Then, in your PHP code, you would just need a bit of logic to display the header for students and staff:
$count = mysqli_num_rows($result);
$type = -1;
while ($count > 0) {
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
$curr_type = $row["type"];
if ($type == -1) {
echo "<h1>Students:</h1>";
$type = 0;
}
else if ($type == 0 && $curr_type == 1) {
echo "<h1>Staff:</h1>";
$type = 1;
}
$name = $row["lastname"];
echo "<p>$name</p>";
--$count;
}
Related
I am trying to add the result of 3 SQL queries. All 3 queries return integer values.
How can I add the results from the 3 SQL queries into a variable and echo it?
The code:
<?php
define('HOST','mywebsite.com');
define('USER','username');
define('PASS','password');
define('DB','imagebase');
$con=mysqli_connect(HOST,USER,PASS,DB);
if($_SERVER['REQUEST_METHOD']=='POST'){
$val1=$_POST['sval1'];
$val2=$_POST['sval2'];
$val3=$_POST['sval3'];
$sql="select price from images where name='$val1'"; //returns 100
$sql1="select price from images where name='$val2'"; //returns 100
$sql2="select price from images where name='$val3'"; //returns 100
$result=mysqli_query($con,$sql);
$count=mysqli_num_rows($result);
$result1=mysqli_query($con,$sql1);
$count1=mysqli_num_rows($result1);
$result2=mysqli_query($con,$sql2);
$count2=mysqli_num_rows($result2);
if ($count==1) {
$res1=$count;
}
if ($count1==1) {
$res2=$count;
}
if ($count2==1) {
$res3=$count;
}
$final=$res1+$res2+$res3; //should return 300 but returns 3
echo $final;
mysqli_close($con);
} else {
echo 'Error Updating Price';
mysqli_close($con);
}
?>
WARNING code in question is VULNERABLE to SQL Injection! Don't do this. Any potentially unsafe values that are included into SQL text must be properly escaped. The preferred pattern is to use prepared statements with bind placeholders.
To address the specific question that was asked: we would need to fetch rows from the resultsets, and accumulate the values returned for price.
It doesn't look like we are concerned with the number of rows that are returned; by each query, so there's not really a reason to call num_rows function.
$tot = 0;
$result=mysqli_query($con,$sql);
while( $row = $result->fetch_assoc() ) {
$tot += $row['price'];
}
$result1=mysqli_query($con,$sql1);
while( $row = $result1->fetch_assoc() ) {
$tot += $row['price'];
}
$result2=mysqli_query($con,$sql2);
while( $row = $result2->fetch_assoc() ) {
$tot += $row['price'];
}
echo "tot = " . $tot;
But why that whole rigmarole of running three separate queries? If what we want is a total, we could have MySQL calculate that for us.
Also, the object oriented pattern is much easier than the procedural pattern.
$sql = 'SELECT SUM(i.price) AS tot_price
FROM images i
WHERE i.name IN ( ? , ? , ? )';
if( $sth = $con->prepare($sql) ) {
$sth->bind_param('sss',$val1,$val2,$val3);
if( $sth->execute() ) {
$sth->bind_result($tot_price);
if( $sth->fetch() ) {
echo "tot_price = " . $tot_price;
} else {
// no row returned
}
$sth->close();
} else {
// handle error in execute
} else {
// handle error in prepare
}
Inside your if statements, you forgot to change $count to $count1 and $count2 in second and third statements.
Also, are you sure you want to check that $count, $count1, $count2 are equal to 1?
You may want to check if those variable have falsy value so if($count) etc.
After that, you need to initialize $res1, $res2, $res3 to 0 before the if statement, otherwise it can occour you get error later when summing $res variables that are not initialized due to falsy if statement before.
Im trying to sum up all the values in this data base but for some reason i cant do i, I looked all over stack overflow and tried multiple methods but none seem to work. My current code is
<?php
error_reporting(0);
//INCLUDES//
include 'config.php';
//INCLUDES//
//DATA FETCH//
$rank=$_POST['R'];
$drank=$_POST['DR'];
//DATA FETCH//
//MYSQL STUFF//
$con=mysqli_connect($ip,$login,$password,$dbname);
for ($i = $rank; $i <= $drank; $i++) { // LOOP UNTIL 20 IS MET
$s=mysqli_query($con, "SELECT sum(rankprice) FROM cost WHERE rank='$i'");
if($s === FALSE) { //CHECK IF DATA IS THERE
die('Error: ' . mysqli_error($con)); // IF NOT THERE SEND ERROR
}
$row = mysqli_fetch_array($s); //PUT DATA IN ROW
echo $row[0];
}
?>
It connects to the database no problem. When I use echo $row[0]; it prints all the values of the column in order. Ive tried putting it into an array and printing it but it seems that doesnt work either. The only way it seems to work is when I add ALL the values in the column by removing WHERE rank='$i' in the SQL code which I dont want to do. Please help !
Try the following query :
$rankarr = array();
for ($i = $rank; $i <= $drank; $i++) { // LOOP UNTIL 20 IS MET
$rankarr[] = $i;
}
$rankarr = implode(',', $rankarr);
$s=mysqli_query($con, "SELECT sum(rankprice) As myrank FROM cost WHERE rank in ($rankarr)");
if($s === FALSE) { //CHECK IF DATA IS THERE
die('Error: ' . mysqli_error($con)); // IF NOT THERE SEND ERROR
}
$row = mysqli_fetch_array($s); //PUT DATA IN ROW
You now want to get the sum value of rankprice in one same rank. So the result of sum() will differ from the rank in one sql. You should tell mysql by adding group by clause, which group the table by rank and get the sum() of each group.
$s=mysqli_query($con, "SELECT sum(rankprice) FROM cost WHERE rank='$i' GROUP BY rank ");
I have php code with two queries. One is in an Oracle database, with the result being about 100 rows of data (within the data there are SKU numbers). The other is in a mysql database with about 30 rows of data (with the data there are also SKU numbers).
I need to compare each SKU in the first query to the second query, line by line. If the SKU in the first query also appears in the second query, then I need it to echo the SKU.
All SKUs in the second query are in the first query, so I would expect the result to echo all 30 SKUs, but it does not. Depending on how I change the syntax, it echos 17 rows, 100 rows, or no rows at all.
It's worth noting that both queries work fine. The Oracle query is insanely long and has a lot of sub-queries in it, so I will not include that full query below. The Oracle query returns the results perfectly in SQL Developer, and the MySQL query returns the results perfectly in HeidiSQL. Both queries have been tested and echoed as tables in other php files to make sure that they were working fine.
Below is what the php file that I am trying to fix looks like so far;
<?php
$conn = oci_connect($user, $pswd, $hst);
$sql = oci_parse($conn,"[Really long Oracle Query]");
while ($row = oci_fetch_assoc($sql))
{
$sku = $row['SKU'];
$con = mysql_connect("[database host]", "[database user]", "[database password]");
mysql_select_db("[database_name]");
$sqls = "SELECT * FROM [table_name] WHERE [this_date_column] BETWEEN
DATE_SUB(NOW(), INTERVAL 14 DAY) AND NOW()";
$result = mysql_query($sqls);
$mailer = NULL;
while($rows = mysql_fetch_assoc($result))
{
$m_sku = $rows['sku'];
if ($m_sku == $sku)
{
$mailer == 'false';
}
}
if ($mailer == 'false')
{
echo $m_sku;
echo "<br>";
}
}
?>
Again; there are only 30 SKUs in the MySQL query, but over 100 SKUs in the Oracle query. All SKUs in the MySQL query are definitely in the Oracle query.
Anyone see what I am doing wrong?
Thanks in advance,
-Anthony
You have basic sintacsis errors:
= is used to assign values
== compares 2 variables (not counsidering there type *)
=== compares 2 variables including there types.
your code should look something like this:
while($rows = mysql_fetch_assoc($result))
{
$m_sku = $rows['sku'];
if ($m_sku == $sku)
{
$mailer = false; // == is for comparison, = is for assign
}
}
if ($mailer === false)
{
echo $m_sku;
echo "<br>";
}
if($member == 'false'){...}
when 'false' is compared with == to a falsefull value (0, null, false, array(), '') .. it will NOT be mach it as it is parsed as a "not empty string" so it is not falsefull .
Here is your code with the MySQL connect moved outside the loop and the == assignment fixed.
<?php
//Connect to databases
$oracle = oci_connect($user, $pswd, $hst);
$mysql = mysql_connect("[database host]", "[database user]", "[database password]");
mysql_select_db("[database_name]");
//Get rows from Oracle
$oracle_result = oci_parse($oracle, "[Really long Oracle Query]");
$oracle_rows = array();
while ($row = oci_fetch_assoc($oracle_result)) $oracle_rows[] = $row;
//Get rows from MySQL
$mysql_sql = "SELECT * FROM [database_name] WHERE this_date_column BETWEEN
DATE_SUB(NOW(), INTERVAL 14 DAY) AND NOW()";
$mysql_result = mysql_query($mysql_sql);
$mysql_rows = array();
while ($row = mysql_fetch_assoc($mysql_result)) $mysql_rows[] = $row;
foreach ($oracle_rows as $oracle_row) {
$oracle_sku = $oracle_row['SKU'];
foreach ($mysql_rows as $mysql_row) {
$mysql_sku = $mysql_row['sku'];
$mailer = null;
if ($mysql_sku == $oracle_sku) {
$mailer = false;
echo $mysql_sku . "<br>";
}
}
}
I have this script below where it scans users that are allowed to see a post. How do i update it so that it will match the person viewing's ID to the one stored in the field. If it matches it works else it doesn't. The stored entries will be something like 99394david, 324234smith, 34343jane. So this script i have is not matching it.
$kit = mysql_real_escape_string($_GET['id']);
$sql="SELECT `Who_can_see` from `posts` where `post_id` = '$kit'";
$result=mysql_query($sql);
$query = mysql_query($sql) or die ("Error: ".mysql_error());
if ($result == "")
{
echo "";
}
echo "";
$rows = mysql_num_rows($result);
if($rows == 0)
{
print("");
}
elseif($rows > 0)
{
while($row = mysql_fetch_array($query))
{
$userallowed = htmlspecialchars($row['who_can_see']);
}
}
//$personid is drawn from the database. its the id of the
person viewing the link.
if ( $userallowed == $personid ) {
echo("allowed");
} else {
echo("not allowed");
die();
}
?>
I would simply add the $personid to the query (although I have doubts about how you are filling your posts table exactly...):
$sql="SELECT `Who_can_see` from `posts`
where `post_id` = '$kit'
AND `Who_can_see` = '$personid'";
If your result contains a row, the user is allowed to view the post.
By the way, I would also recommend using prepared statements to avoid any potential sql injection problems.
Edit: Based on the fact that Who_can_see can contain a comma separated list of entries, you can use your original script, and just change how you match, using for example stripos.
if ( stripos($userallowed, $personid) !== false ) {
// $personid is found in $userallowed
echo("allowed");
} else {
echo("not allowed");
die();
}
I am trying to create a class registration system for a client that utilizes PHP and MySQL. I have the database and table all set up and that part works just fine, however, the client has requested that upon registration, if there are 3 or fewer students enrolled to warn that the class may not run.
I'm trying to use the count() function as well as passing a dynamic variable from a cookie, set from the registration PHP script. However, I've hit a roadblock. I can't seem to get the count() function to actually count the rows. My select statement is below. Any help would be greatly appreciated.
$class = $_COOKIE["class"];
$min_check = "SELECT class_list, COUNT(class_list) as count
FROM T_Student WHERE class_list = '$class'
GROUP BY class_list
HAVING count < 20";
$result = mysql_query($min_check);
$count = mysql_num_rows($result);
if ($count < 4)
{
echo "IF THERE ARE 3 OR FEWER PEOPLE SIGNED UP FOR THIS CLASS, IT MAY NOT RUN.\n";
echo "THERE ARE CURRENTLY " . $count . " PEOPLE SIGNED UP.\n";
}
else if ($count > 4)
{
echo "There are currently " . $count . " people signed up for this class.";
}
?>
Your SQL query is returning a list of the class_list values, along with a count of each specific instance, where there are less than 20 people registered.
$count = mysql_num_rows($result);
...is getting the number of records returned in the resultset, not the alias count value, which is why you aren't seeing the output you expect. You need to read into your resultset to get the value:
while ($row = mysql_fetch_assoc($result)) {
$count = $row['count'];
if($count < 4) { ... }
}
The count that you want is returned in the row of the query. the mysql_num_rows will count the rows returned, which is not what you want. Use this instead.
$result = mysql_query($min_check);
$count = mysql_fetch_row($result);
$count = $count[0];
On a first glance, the HAVING count < 20 is unnecessary.
You use the MySQL-count-function, but never retrieve it's value!? Use:
$firstRow = mysql_fetch_row($result);
$count = $firstRow[1]; // 1 indicates the second column (0 being the first)
I don't recommend using known MySQL identifiers like count. It's confusing.
$class = mysql_real_escape_string($_COOKIE["class"]);
$min_check = "SELECT class_list, COUNT(class_list) as mycount
FROM T_Student WHERE class_list = '$class'
GROUP BY class_list
HAVING mycount < 20";
Don't forget to escape the contents of that cookie!
The error is that count is a reserved word. You need to either surround it in backticks `count` or even better, use a different moniker. It's not an error per se, but it's just too confusing.
Next up, you are not actually retrieving the mycount result from the database. I suggest using code something like this:
$result = mysql_query($min_check);
while( $row = mysql_fetch_assoc($result) ) {
$people_count = $row['mycount'];
if ($people_count < 4) { echo "this" }
else { echo "that" }
}