Nested PDO queries - php

I've run into some trouble trying to execute MSSQL queries using PDO.
I have a table called Computer with 92 computers listed. They all have a respective ID 1-92.
I am using the query: SELECT * FROM Computer to query the table. I want to add associated information to this query so I am outputting it inside a while-loop (this is eventually for table generation).
$queryDiskOperationLog = "SELECT * FROM Computer";
$queryHDDSResult = $connClient -> prepare($queryDiskOperationLog);
$queryHDDSResult->execute();
$queryDiskOperationLogResult = $connClient -> prepare($queryDiskOperationLog);
while ($rowHDDS = $queryHDDSResult->fetch(PDO::FETCH_ASSOC)) {
echo $rowHDDS['Id'];
}
This output works great. I get 1-92 outputted. Trouble begins when I start adding other queries.
Whenever I add another query inside the while-loop the output of the first query is altered and it only outputs uneven numbers (ie. 1,3,5,7...)
I am using the same PDO::FETCH_ASSOC method to get results from the other query and variable names are distinctly different. Do you know what could cause this?
My final code looks like: (note I don't even echo the second query yet.
$queryDiskOperationLog = "SELECT * FROM Computer";
$queryHardDisk = "SELECT * FROM HardDisk";
$queryHDDSResult = $connClient -> prepare($queryDiskOperationLog);
$queryHDDSResult->execute();
$queryHardDiskResult = $connClient -> prepare($queryHardDisk);
$queryHardDiskResult ->execute();
$queryDiskOperationLogResult = $connClient -> prepare($queryDiskOperationLog);
while ($rowHDDS = $queryHDDSResult->fetch(PDO::FETCH_ASSOC)) {
$rowHardDisk = $queryHardDiskResult->fetch(PDO::FETCH_ASSOC);
echo $rowHDDS['Id'];
}

Related

Select statement fill data in a foreach

I'm trying to create a php file that when clicking a 'Edit' Link it will get that job ID and list the number of rows by jobRef in my applications table.
This is just to list all of the applications for the different jobs i have available on my website.
<?php
require 'mysqlcon.php';
if(isset($_GET['id']))
{
$stmt = $pdo->query('SELECT FROM applications WHERE applicationID = :id');
$results = $stmt->fetchAll();
echo "<table><tr><td>Job Reference</td><td>Job Title</td><td>Job Location</td><td>Job Description</td><td>Salary</td><td>Availability</td> <td>Category</td><td>Apply</td>";
foreach ($results as $row) {
echo "<tr><td>".$row['applicationID']."</td>". "<td>".$row['jobRef']."</td>", "<td>".$row['fName']."</td>", "<td>".$row['lName']."</td>";
}
}
?>
My error is that i cannot get my code to work; I've tried using "PDO::FETCH_ASSOC" but still no help.
Any ideas on where i've gone wrong?
You need to use prepare and execute, for binding/parameterized queries. You also need to pass the value to the query. Try this:
$stmt = $pdo->prepare('SELECT * FROM applications WHERE applicationID = ?');
$stmt->execute(array($_GET['id']));
$results = $stmt->fetchAll();
Your select query also needs the value that your are selecting. I've put in * which is every column. If you only want some columns list them separated by commas.
The concatenation and comma separation in your echo is strange but I think should work..
Final note, your table doesn't close; you should add a </table> after the foreach.
Final additional note for errors use, http://php.net/manual/en/pdo.errorinfo.php.

MySQL SELECT query works in PHPmyadmin, not in PHP

So, Im having a lot of trouble with executing a query in PHP. It executes well in phpmyadmin and gives me a neat list of results.
Here is the query I inserted into phpmyadmin:
SELECT RIGHT(`Pair`, LOCATE('_', REVERSE(`Pair`))-1)
FROM `poloniex`
WHERE LEFT(`Pair`, 3) = 'BTC';
For example an entry in the Column Pair: BTC_NXT
The query should return NXT (everything right of the "_").
Now, when switching over to php while I haven't edited the query at all, I don't get any result.
The dbconnection is already established; no problems on that front.
$query_get_pairs = "SELECT RIGHT(`Pair`,LOCATE('_',REVERSE(`Pair`))-1) FROM `poloniex` WHERE LEFT(`Pair`, 3) = 'BTC'";
$result_get_pairs = mysqli_query($dbc,$query_get_pairs);
var_dump($result_get_pairs) returns an empty array.
Summary:
poloniex is the table name.
Pair is the column name which
contains values like "BTC_NXT". The query should give me NXT.
You are not fetching anything, your code should be like:
$query_get_pairs = "SELECT RIGHT(Pair,LOCATE('_',REVERSE(Pair))-1) FROM poloniex WHERE LEFT(Pair, 3) = 'BTC'";
$result_get_pairs = mysqli_query($query_get_pairs);
$myResult = mysqli_fetch_assoc($result_get_pairs);
var_dump($myResult);

Migrating to MYSQLI : How to fitch result of query in while(list()) method instead of foreach() method?

I have very large PHP website, about 3000+ PHP files, all files are linked to main class named (lib.inc.php) which includes :
config.inc.php
users.inc.php
mysql.inc.php
I am doing quick migration from MYSQL to MYSQLI , and I am planning to do very minimal changes in MYSQL part, I did found many MYSQLI Classes which I can replace it with my old mysql.inc.php , but thats was not the big part of the job ... The big part is I have to change the code of the queries in almost each PHP file, I have around 3 to 5 MYSQL Queries which is currently in the following format structure :
$query = "
SELECT USER_ID,USER_NAME,USER_EMAIL,USER_LEVEL,USER_REG_DATE,USER_LAST_ACCESS,USER_LAST_IP
FROM USERS_TBL
LIMIT 0,20
";
$sth = $dbh -> do_query($query);
while (list($USER_ID,USER_NAME,USER_EMAIL,USER_LEVEL,USER_REG_DATE,USER_LAST_ACCESS,USER_LAST_IP) = $dbh -> fetch_array($sth)) {
// Do some thing with the result and print it
}
IN mysql.inc.php : I have the following Functions related to the above code :
function do_query($query) {
$this->sth = mysql_query($query,$this->dbh);
return $this->sth;
}
function fetch_array($sth) {
$this->row = mysql_fetch_array($sth);
return $this->row;
}
My question is :
How to migrate the above code from MYSQL to MYSQLI keeping in mind that I dont want to change the structure of loop part , as I want to all my while loops remain the same in all 3000+ PHP files , specially this part :
while (list($USER_ID,$USER_NAME,$USER_EMAIL,$USER_LEVEL,$USER_REG_DATE,$USER_LAST_ACCESS,USER_LAST_IP) = $dbh -> fetch_array($sth)) {
// Do some thing with the result and print it
}
In the current MYSQLI classes which I found in the net , all statements witch dealing with fetching array it has the following structure:
/**
* Retrieve results of a standard query
*/
$query = "SELECT USER_ID,USER_NAME,USER_EMAIL,USER_LEVEL,USER_REG_DATE,USER_LAST_ACCESS,USER_LAST_IP
FROM USERS_TBL
LIMIT 0,20";
$results = $database->get_results( $query );
foreach( $results as $row )
{
$USER_ID = $row['USER_ID'];
$USER_NAME = $row['USER_NAME'];
$USER_EMAIL = $row['USER_EMAIL'];
$USER_LEVEL = $row['USER_LEVEL'];
$USER_REG_DATE = $row['USER_REG_DATE'];
$USER_LAST_ACCESS = $row['USER_LAST_ACCESS'];
$USER_LAST_IP = $row['USER_LAST_IP'];
}
Notice that in mysqli version I have to assign each variable to another one so I can use them in different places in the code, but in my old code , I just need to type the variable inside the while (list(....)) methods .. instead of making each variables in separate line....changing the while(list()) methods to foreach() method will cost me hundreds of hours to apply this changes in my whole codes of 3000+ PHP files 600,000 lines of code .
So , How to apply current methods code in mysqli version ???
if I can get example of fetching result in while(list()) way using MYSQLI ,I will be much appreciated.

magento make multiple database connections without losing array values

I am trying to make connections to two different databases so my script should work as follows
Find all orders for the current logged in customer where the order state is complete, it is a virtual product and it has a juno order id (this query works fine)
Collect all of order ids that have been found and store them in an array (this works fine)
now connect to sales_order_items and for each item that is part of an order id check to see if the database has a url download link,
if not i will connect to an api --
the problem is when i want to make my second connection i seem to lose all the values that are stored in the $orderIds array.
i have been looking for solutions but i am pretty new to the zend framework
any help would be much appreciated
my script is as follows
$conn = Mage::getSingleton('core/resource')->getConnection('core_write');
$result = $conn->query('select * from sales_flat_order WHERE customer_id='.$session->getCustomerId().' AND state="complete" AND is_virtual=1 AND juno_order_id!="null"');
$orderIds=array();
foreach ($result as $orderId)
{
$orderIds[]=$orderId[entity_id];
$itemsonOrder=$conn->query('select * from sales_flat_order_items WHERE order_id='.$order[entity_id]);
}
// value of first array $orderIds gets lost if i make annother connection using $conn
echo 'items on order';
print_r($itemsonOrder);
echo '<pre>';
print_r($orderIds);
echo '</pre>';
Well you aren't done with the first query yet when you are connecting with the second query. Go ahead and finish with the first query, then start the second one. Try something more like this...
$conn = Mage::getSingleton('core/resource')->getConnection('core_write');
$result = $conn->query('select * from sales_flat_order WHERE customer_id='.$session->getCustomerId().' AND state="complete" AND is_virtual=1 AND juno_order_id!="null"');
$orderIds=array();
foreach ($result as $orderId)
{
$orderIds[]=$orderId[entity_id];
}
foreach ($orderIds as $orderId)
{
$itemsonOrder=$conn->query('select * from sales_flat_order_items WHERE order_id='.$orderId);
}
Also, you should probably make sure you are using parameters when doing queries. Concatenating sql strings like that can be dangerous (leaves you open to vulnerabilities sometimes). For example,
$conn->query('select * from sales_flat_order_items WHERE order_id='.$orderId);
should be changed to
$conn->query('select * from sales_flat_order_items WHERE order_id=?', array($orderId));
Also, do you really need to "select *"??? I mean, just select the columns you need.

How to get "field names" using PHP ADOdb?

I'm using PHP ADOdb and I can get the result set:
$result = &$db->Execute($query);
How do I get the field names from that one row and loop through it?
(I'm using access database if that matters.)
It will depend on your fetch mode - if you setFetchMode to ADODB_FETCH_NUM (probably the default) each row contains a flat array of columns. If you setFetchMode to ADODB_FETCH_ASSOC you get an associative array where you can access each value by a key. The following is taken from ADODB documentation - http://phplens.com/lens/adodb/docs-adodb.htm#ex1
$db->SetFetchMode(ADODB_FETCH_NUM);
$rs1 = $db->Execute('select * from table');
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1')
print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')
To loop through a set of results:
$result = &$db->Execute($query);
foreach ($result as $row) {
print_r($row);
}
Small improvement to the solution posted by #thetaiko.
If you are ONLY needing the field names, append LIMIT 1 to the end of your select statement (as shown below). This will tell the server to send you a single row with column names, rather than sending you the entire table.
SELECT * FROM table LIMIT 1;
I'm working with a table that contains 9.1M records, so this minor change speeds up the query significantly!
This is a function I use to return a field array - I've stripped out some extra stuff that, for example, allows it to work with other DBs than MySQL.
function getFieldNames($strTable, $cn) {
$aRet = array();
# Get Field Names:
$lngCountFields = 0;
$strSQL = "SELECT * FROM $strTable LIMIT 1;";
$rs = $cn->Execute($strSQL)
or die("Error in query: \n$strSQL\n" . $cn->ErrorMsg());
if (!$rs->EOF) {
for ($i = 0; $i < $rs->FieldCount(); $i++) {
$fld = $rs->FetchField($i);
$aRet[$lngCountFields] = $fld->name;
$lngCountFields++;
}
}
$rs->Close();
$rs = null;
return $aRet;
}
Edit: just to point out that, as I say, I've stripped out some extra stuff, and the EOF check is therefore no longer necessary in the above, reduced version.
I initally tried to use MetaColumnNames, but it gave differing results in VisualPHPUnit and actual site, while running from the same server, so eventually
I ended up doing something like this:
$sql = "select column_name, column_key, column_default, data_type, table_name, table_schema from information_schema.columns";
$sql .= ' where table_name="'.$table.'" and table_schema="'.$database_name.'"';
$result = $conn->Execute($sql);
while($row = $result->fetchRow()) {
$out[] = strToUpper($row['column_name']);
}
I think it should work with mysql, mssql and postgres.
The benefit of doing it like this, is that you can get the column names, even if a query from a table returns an empty set.
If you need the Coloumn names even for empty tables or for joins about multiple tables use this:
$db->Execute("SELECT .......");
// FieldTypesArray - Reads ColoumnInfo from Result, even for Joins
$colInfo = $res->FieldTypesArray();
$colNames = array();
foreach($colInfo as $info) $colNames[] = $info->name;
The OP is asking for a list of fieldnames that would result of executing an sql statement stored in $query.
Using $result->fetchRow(), even with fetch mode set to associative, will return nothing if no records match the criteria set by $query. The $result->fields array would also be empty and would give no information for getting the fieldnames list.
Actually, we don't know what's inside the $query statement. Besides, setting limit to 1 may not compatible with all database drivers supported by PHP ADOdb.
Answer by Radon8472 is the right one, but the correct code could be:
$result = $db->Execute($query);
// FieldTypesArray - an array of ADOFieldObject Objects
// read from $result, even for empty sets or when
// using * as field list.
$colInfo = [];
if (is_subclass_of($result, 'ADORecordSet')){
foreach ($result->FieldTypesArray() as $info) {
$colInfo[] = $info->name;
}
}
I have the habit of checking the class name of $result, for as PHP ADOdb will return false if execution fails.

Categories