Working with WordPress, running a custom query to pull all records relating to a specific condition. When I run the query in phpmyadmin it returns all records, when I run the query through PHP code, only 2-5 results return, need to find out how to resolve this:
// get variables from form page
$txtReg = $_REQUEST['txtReg'];
$txtMsg = $_REQUEST['txtMsg'];
// connect to database
$mydb = new
wpdb('***','***','***','***');
// run the query to fetch all cell numbers from the region variable
$query = "SELECT * FROM tblusers WHERE `Region` ='$txtReg'";
$rows = $mydb->get_results($query);
// display all cell numbers from that region
foreach ($rows as $row) {
$txtCell = $row->Cell;
//doSendSMS($txtCell,$txtMsg);
echo $txtCell;
}
E.g there are 100 cell numbers in Region A, only a few are returned and echoed, not all 100 like it should be, so when I run the sms code (which is the actual function, echo is used just to test results), not all receive the sms.
#Caius Jard was correct about the settings in the database, it was in fact limited even though no limit clause was applied in the sql query itself. The code is functional in my setup but was limited by the default settings.
tested using:
$query = "SELECT * FROM tblusers WHERE Region ='$txtReg' LIMIT 100";
Related
I have a sql query returning the average and count of results matching column values. The issue is that $wpdb results works but only fetches the result for the first value in the dynamic query. To test, I have had the query it is constructing echo'ed to the page and when querying the database with php myadmin it fetches the result correctly (returns bother employer_name possibilities).
Also, when hardcoding this static query into $wpdb->get_results it also works fine. However, when running through $wpdb->prepare, although it sanitises and echos out a seemingly identical query to the hardcoded query, the result does not take the second argument for employer_name into account and only searches for values matching the first value for employer name, not both.
$test sql below is the query manually written and this works and fetches results for both employer name values
$test_sql = "SELECT COUNT(salary),AVG(salary) FROM table_name WHERE city = 'city'
AND pending <> 'pending' AND employer_name = 'employer_name' OR
employer_name = 'employer_name_two'";
This is the dynamic sql constructor for the above example. Although it echo's out the seemingly identical query it discounts the second value for employer_name and thus only fetches some of the values.
$dynamic_sql = "SELECT COUNT(salary),AVG(salary) FROM table_name WHERE
city = %s AND pending <> %s AND employer_name = %s OR employer_name = %s";
$safe_sql = $wpdb->prepare($dynamic_sql,array( $city_name, 'pending', $employer_name,
$employer_name_two));
$result = $wpdb->get_results($safe_sql);
What am I missing? Thanks.
I want to get how many (possibly 0) times a particular number occurs in a particular column. I set the number in $contact_client_ID then do the SELECT query below.
$sql = "SELECT * FROM t_contacts WHERE contact_client_ID ='$contact_client_ID'";
$result=(mysqli_query($link, $sql));
$count_result= mysqli_num_rows($result);
echo "contact client ID $contact_client_ID xxxxx $count_result";
Instead of $count_result containing the number I want, it contains a result made up of the number I want and the contact_client_ID joined together and the result doesn't seem to be usable as a number in any following code.
So, if $contact_client_ID = 50 and there are 2 occurrences of it in the table, the output I get is:
contact client ID 50 xxxxx 250
I've looked at the manuals and examples all over the place (including here) and I can't see what I'm doing wrong.
There are multiple ways of doing this, more precisely you have the option, to either do the count in PHP, or make your SQL server do the counting and just return the number:
Do it in PHP:
What it requires is: - fetch all data; -make a counter variable; - loop trough the data, for each loop increase counter +1
For small tables you can use PHP, for bigger ones I advice doing it on the SQL, since for PHP to count it it must fetch all the data.
$counter=0;
$query = "SELECT * FROM t_contacts WHERE contact_client_ID ='$contact_client_ID";
$res = $con->query($query);
while ($row = $res->fetch_assoc()) {
$counter++;
}
Do it in SQL
Now the smarter way would be to do it on the SQL server ,as it would handle the load better;
I would say what /u/Adaleni wrote is pretty close to what I would use:
$sql = "SELECT count(contact_client_ID) as total FROM t_contacts WHERE contact_client_ID ='$contact_client_ID'";
$result=mysqli_query($link, $sql);
$count_result= mysqli_fetch_row(result);
echo "contact client ID $contact_client_ID xxxxx $count_result[0]['total']";
Lets just describe what he does:
we use COUNT() function in SQL, this makes the server count the number of occurances of contact_client_ID and then make (in the result) a new variable called "total"
we execute the query and get the result
We use mysqli_fetch_rowm this function gets the result row as an enumerated array
then we access that array (as we know its only 1 item, we accessed index 0) and we print the variable total which we made in step 1 - $count_result[0]['total']
Try this
/* Select queries return a resultset */
if ($result = $mysqli->query("SELECT * FROM t_contacts WHERE contact_client_ID ='$contact_client_ID")) {
printf("Select returned %d rows.\n", $result->num_rows);
I'm not sure if I am asking this the correct way, but I want to run a query on an Oracle database, fetch the result, and then run additional queries on that result dataset. Is that possible? I am trying to avoid another call to the database.
$query = "SELECT * FROM MY.TABLE ";
$stid = oci_parse($connection, $query);
oci_execute($stid);
while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS_OCI_RETURN_LOBS)) {
//my code for the full dataset
}
Then I would like to do something like
PSUEDO-CODE
$newDataset = runThisQuery("SELECT * FROM [oci dataset from above(what is that syntax?)] WHERE my_value = 1");
while($newRow = loop through $newDataset){
//my code for the subquery
}
Any suggestions?
To further describe my problem: I am getting a table of fields, and from that table I would like to extract the unique values of certain fields into their own php arrays.
im trying to display a tracking number for a product on opencart.
so once the order has been placed. i then add a tracking number to it. from which i wish the customer to be able to see on the order history.
// get tracking details
$sql = 'SELECT * FROM '.DB_PREFIX.'order_history'.`tracking_number`;
$query = $this->db->query($sql);
$rates = array();
foreach($query->rows as $result){
$rates[] = $result;
}
$this->data['tracking'] = $tracking;
this would also go in order.php
this is what ive written but it dont work, im not expert at php, i dabble in it. hopefully someone can point me in the right direction,
so this code would go into controller/account/order.php
then on the template i assume i can just insert
<?php echo $tracking; ?> to display tracking deteails.
thanks in advance.
Off hand, I can see that this code will result in error, because your quotes/backticks are out of place:
$sql = 'SELECT * FROM '.DB_PREFIX.'order_history'.`tracking_number`;
Should be more along these lines:
$sql = "SELECT `tracking_number` FROM `".DB_PREFIX."order_history`";
And, assuming you're going to want to pull an order-specific tracking #:
$sql = "SELECT `tracking_number`
FROM `".DB_PREFIX."order_history`
WHERE `order_id` = 'MUFFINS'";
Do yourself a favor and use the double quotes when preparing a MySQL query. It's easier to wrap your stuff in single quotes without having to escape.
As for the remainder of the code, these are not rates but tracking numbers. Assumedly, there would be one tracking number to return per order, which you could wrap up into a single line of code like so:
$my_tracking_number = $this->db->query("
SELECT `tracking_number`
FROM `".DB_PREFIX."order_history`
WHERE `order_id` = 'MUFFINS'
")->row['tracking_number'];
if ( !empty($my_tracking_number) {
$this->data['tracking_number'] = $my_tracking_number;
}
However, if you're going to associate more than one tracking number with an order you can either insert a BLOB column in your order_history table and insert/query serialized data, or create a separate table entirely where multiple rows can be associated with a single order ID.
I need to synchronize specific information between two databases (one mysql, the other a remote hosted SQL Server database) for thousands of rows. When I execute this php file it gets stuck/timeouts after several minutes I guess, so I wonder how I can fix this issue and maybe also optimize the way of "synchronizing" it.
What the code needs to do:
Basically I want to get for every row (= one account) in my database which gets updated - two specific pieces of information (= 2 SELECT queries) from another SQL Server database. Therefore I use a foreach loop which creates 2 SQL queries for each row and afterwards I update those information into 2 columns of this row. We talk about ~10k Rows which needs to run thru this foreach loop.
My idea which may help?
I have heard about things like PDO Transactions which should collect all those queries and sending them afterwards in a package of all SELECT queries, but I have no idea whether I use them correctly or whether they even help in such cases.
This is my current code, which is timing out after few minutes:
// DBH => MSSQL DB | DB => MySQL DB
$dbh->beginTransaction();
// Get all referral IDs which needs to be updated:
$listAccounts = "SELECT * FROM Gifting WHERE refsCompleted <= 100 ORDER BY idGifting ASC";
$ps_listAccounts = $db->prepare($listAccounts);
$ps_listAccounts->execute();
foreach($ps_listAccounts as $row) {
$refid=$row['refId'];
// Refsinserted
$refsInserted = "SELECT count(username) as done FROM accounts WHERE referral='$refid'";
$ps_refsInserted = $dbh->prepare($refsInserted);
$ps_refsInserted->execute();
$row = $ps_refsInserted->fetch();
$refsInserted = $row['done'];
// Refscompleted
$refsCompleted = "SELECT count(username) as done FROM accounts WHERE referral='$refid' AND finished=1";
$ps_refsCompleted = $dbh->prepare($refsCompleted);
$ps_refsCompleted->execute();
$row2 = $ps_refsCompleted->fetch();
$refsCompleted = $row2['done'];
// Update fields for local order db
$updateGifting = "UPDATE Gifting SET refsInserted = :refsInserted, refsCompleted = :refsCompleted WHERE refId = :refId";
$ps_updateGifting = $db->prepare($updateGifting);
$ps_updateGifting->bindParam(':refsInserted', $refsInserted);
$ps_updateGifting->bindParam(':refsCompleted', $refsCompleted);
$ps_updateGifting->bindParam(':refId', $refid);
$ps_updateGifting->execute();
echo "$refid: $refsInserted Refs inserted / $refsCompleted Refs completed<br>";
}
$dbh->commit();
You can do all of that in one query with a correlated sub-query:
UPDATE Gifting
SET
refsInserted=(SELECT COUNT(USERNAME)
FROM accounts
WHERE referral=Gifting.refId),
refsCompleted=(SELECT COUNT(USERNAME)
FROM accounts
WHERE referral=Gifting.refId
AND finished=1)
A correlated sub-query is essentially using a sub-query (query within a query) that references the parent query. So notice that in each of the sub-queries I am referencing the Gifting.refId column in the where clause of each sub-query. While this isn't the best for performance because each of those sub-queries still has to run independent of the other queries, it would perform much better (and likely as good as you are going to get) than what you have there.
Edit:
And just for reference. I don't know if a transaction will help here at all. Typically they are used when you have several queries that depend on each other and to give you a way to rollback if one fails. For example, banking transactions. You don't want the balance to deduct some amount until a purchase has been inserted. And if the purchase fails inserting for some reason, you want to rollback the change to the balance. So when inserting a purchase, you start a transaction, run the update balance query and the insert purchase query and only if both go in correctly and have been validated do you commit to save.
Edit2:
If I were doing this, without doing an export/import this is what I would do. This makes a few assumptions though. First is that you are using a mssql 2008 or newer and second is that the referral id is always a number. I'm also using a temp table that I insert numbers into because you can insert multiple rows easily with a single query and then run a single update query to update the gifting table. This temp table follows the structure CREATE TABLE tempTable (refId int, done int, total int).
//get list of referral accounts
//if you are using one column, only query for one column
$listAccounts = "SELECT DISTINCT refId FROM Gifting WHERE refsCompleted <= 100 ORDER BY idGifting ASC";
$ps_listAccounts = $db->prepare($listAccounts);
$ps_listAccounts->execute();
//loop over and get list of refIds from above.
$refIds = array();
foreach($ps_listAccounts as $row){
$refIds[] = $row['refId'];
}
if(count($refIds) > 0){
//implode into string for use in query below
$refIds = implode(',',$refIds);
//select out total count
$totalCount = "SELECT referral, COUNT(username) AS cnt FROM accounts WHERE referral IN ($refIds) GROUP BY referral";
$ps_totalCounts = $dbh->prepare($totalCount);
$ps_totalCounts->execute();
//add to array of counts
$counts = array();
//loop over total counts
foreach($ps_totalCounts as $row){
//if referral id not found, add it
if(!isset($counts[$row['referral']])){
$counts[$row['referral']] = array('total'=>0,'done'=>0);
}
//add to count
$counts[$row['referral']]['total'] += $row['cnt'];
}
$doneCount = "SELECT referral, COUNT(username) AS cnt FROM accounts WHERE finished=1 AND referral IN ($refIds) GROUP BY referral";
$ps_doneCounts = $dbh->prepare($doneCount);
$ps_doneCounts->execute();
//loop over total counts
foreach($ps_totalCounts as $row){
//if referral id not found, add it
if(!isset($counts[$row['referral']])){
$counts[$row['referral']] = array('total'=>0,'done'=>0);
}
//add to count
$counts[$row['referral']]['done'] += $row['cnt'];
}
//now loop over counts and generate insert queries to a temp table.
//I suggest using a temp table because you can insert multiple rows
//in one query and then the update is one query.
$sqlInsertList = array();
foreach($count as $refId=>$count){
$sqlInsertList[] = "({$refId}, {$count['done']}, {$count['total']})";
}
//clear out the temp table first so we are only inserting new rows
$truncSql = "TRUNCATE TABLE tempTable";
$ps_trunc = $db->prepare($truncSql);
$ps_trunc->execute();
//make insert sql with multiple insert rows
$insertSql = "INSERT INTO tempTable (refId, done, total) VALUES ".implode(',',$sqlInsertList);
//prepare sql for insert into mssql
$ps_insert = $db->prepare($insertSql);
$ps_insert->execute();
//sql to update existing rows
$updateSql = "UPDATE Gifting
SET refsInserted=(SELECT total FROM tempTable WHERE refId=Gifting.refId),
refsCompleted=(SELECT done FROM tempTable WHERE refId=Gifting.refId)
WHERE refId IN (SELECT refId FROM tempTable)
AND refsCompleted <= 100";
$ps_update = $db->prepare($updateSql);
$ps_update->execute();
} else {
echo "There were no reference ids found from \$dbh";
}