I have a script that is pretty straight forward in theory, where I"m trying to select relational data on a development DB2 database, and insert into a separate production db2 server (creating new IDs and relationships on the production side in the process).
So in this script, I:
Select from the dev ITEM table
Store the original primary key
insert the data into the dev ITEM table
Get the ID of the newly inserted one
select SUBITEM from dev with the original ID
for each subitem I insert the data into the prod SUBITEM table with the newly created ITEM ID as the relationship
The problem is the script actually runs successfully, but as it goes, it simply increases by one so even though it inserts each ITEM correctly, it ends up just getting EVERY subitem in the database and storing the original (1st row's) ID. FOr instance:
My first ITEM select returns ID 1204. By the time I let it run for several items, my ITEM table shows records with IDs: 1204,1205,1206 and 1207
That's correct, but when I look at the subITEMS table, I have 10 subITEM records all with itemID of 1204. So it got the right subitem for each iteration of ITEMS but only ever inserted the very first newID variable.
What did I do wrong here:
if($DB2connDEV && $DB2connPROD){
$getDevItems = "
SELECT
itemt_ID,
DESCRIPTION
FROM itemt
";
$stmt = odbc_exec($DB2connDEV, $getDevItems);
while($gettingDevItems = odbc_fetch_array($stmt)){
$rows[] = $gettingDevItems;
}
foreach($rows as $row){
$prepInsert = odbc_prepare($DB2connPROD, "INSERT INTO itemt (itemt_id, description) VALUES(?,?)");
$originalID = $row['itemt_ID'];
$description = $row['DESCRIPTION'];
$insertTable = odbc_execute($prepInsert, array($description));
//Get newly created ID
$getIdentity = "SELECT IDENTITY_VAL_LOCAL() AS LASTID FROM SYSIBM.SYSDUMMY1";
$stmt = odbc_exec($DB2connPROD, $getIdentity);
$row = odbc_fetch_array($stmt);
$newID = $row['LASTID'];
if($newID) {
echo "Last Insert ID is : " . $newID . "\n";
} else {
echo "No Last insert ID.\n";
}
//Get subItems and insert
$getSubItems = "SELECT NAME, DESCRIPTION
FROM SUBITEMT
WHERE itemt_ID = $originalID";
$selectSubItems = odbc_exec($DB2connDEV, $getSubItems);
while($gettingSubItems = odbc_fetch_array($selectSubItems)){
$subItemRows[] = $gettingSubItems;
}
foreach($subItemRows as $subItemRow){
$subItemPrepInsert = odbc_prepare($DB2connPROD, "INSERT INTO subitemt (itemt_id, NAME, DESCRIPTION) VALUES(?,?,?)");
$subItemName = $subItemRow['NAME'];
$subItemDescription = $subItemRow['DESCRIPTION'];
$subtaskInsertExec = odbc_execute($subtaskPrepInsert, array($newID, $subItemName, $subItemDescription));
//get newly created ID for subitem
$getsubtaskID = "SELECT IDENTITY_VAL_LOCAL() AS LASTID FROM SYSIBM.SYSDUMMY1";
$subtaskIDSTMT = odbc_exec($DB2connPROD, $getsubtaskID);
$newsubItemRow = odbc_fetch_array($subtaskIDSTMT);
$newSubItemID = $newsubItemRow['LASTID'];
if($newSubItemID) {
echo "Last Insert subItem ID is : " . $newSubItemID . "\n";
} else {
echo "No Last insert subItem ID.\n";
}
}
}
odbc_close($DB2connPROD);
odbc_close($DB2connDEV);
}
The problem is that you're not clearing out $subItemRows between iterations of the main loop. So each time you're adding the new subitems to the subitems from the previous iterations.
Put
$subItemRows = array();
before the loop:
while($gettingSubItems = odbc_fetch_array($selectSubItems)){
$subItemRows[] = $gettingSubItems;
}
Related
I have a query that requests an ID (the PK) and an order number and throws them into an array. I then loop through the returned data in the array and run two more queries to find the number of times the order number shows up in the database and to get the invoice numbers that belong to that order number. The problem I'm seeing with this setup is that it is taking a while (around 9 seconds) to return the compiled data array. Is there a faster way to get the returned results I'm looking for?
I've tried to find some articles online and came across mysqli_multi_query. Is this the better route to make multiple queries to gather the type of data I am trying to get?
<?php
require 'config.php';
$sql = "SELECT id,internal_order_number FROM orders GROUP BY internal_order_number ORDER BY created_date desc LIMIT 0 ,50";
$query=mysqli_query($mysqli, $sql);
if (!$query) {
throw new Exception(mysqli_error($mysqli)."[ $sql]");
}
$data = array();
while( $row=mysqli_fetch_array($query) ) { // preparing an array
$nestedData=array();
$nestedData['line_id'] = $row["id"];
$nestedData['internal_order_number'] = $row["internal_order_number"];
$data[] = $nestedData;
}
$compiled_data = array();
// Loop through data array with additional queries
foreach($data as $line){
$new_data = array();
// Get item counts
$item_counts = array();
$get_count = " SELECT internal_order_number FROM orders WHERE internal_order_number = '".$line['internal_order_number']."' ";
$count_query=mysqli_query($mysqli, $get_count);
while ($counts=mysqli_fetch_array($count_query)){
if (isset($item_counts[$counts['internal_order_number']])) {
$item_counts[$counts['internal_order_number']]++;
} else {
$item_counts[$counts['internal_order_number']] = 1;
}
}
$product_count = $item_counts[$line['internal_order_number']];
// Get invoice numbers
$invoice_array = array();
$get_invoices = " SELECT invoice_number FROM orders WHERE internal_order_number = '".$line['internal_order_number']."'";
$invoice_query=mysqli_query($mysqli, $get_invoices);
while ($invoice=mysqli_fetch_array($invoice_query)){
if(!in_array($invoice['invoice_number'], $invoice_array)){
$invoice_array[] = $invoice['invoice_number'];
}
}
$invoices = implode(", ",$invoice_array);
$new_data['order_number'] = $line['internal_order_number'];
$new_data['count'] = $product_count;
$new_data['invoices'] = $invoices;
$compiled_data[] = $new_data;
}
mysqli_close($mysqli);
print_r($compiled_data);
?>
What, why are you doing basically the same query 3 times. You first one selects them all, you second query requires the same table making sure the first tables order number == the tables order number and the last just grabs the invoice number...?
Just do one query:
SELECT internal_order_number, invoice_number FROM table WHERE ...
Then loop through it and do what you need. You don't need 3 queries...
I have a php API where i am checking different conditions and based on that, i am fetching the count of the row and updating the count in the same table.
Below are the Conditions i am writing the query: (Note: 1 user can have multiple campaigns)
1) For a given user(Uid), for a particular campaign whose type = Impression, i am getting the Impression count and updating the same in table
2) For a given user(Uid), for a particular campaign whose type = Action i am getting the Action count and updating the same in table
//To get the Impression/Action/Lead count
$Impressionarr = [];
$Actionarr = [];
//IMPRESSION COUNT
$imp_qry = "select count(*) as ImpressionCount from ClicksAndImpressions where Uid = 101642 and CampaignID =100 and Type='Impression' ;";
$impData = $this->getClicksAndImpressionsTable()->CustomQuery($imp_qry);
if($impData[0]['ImpressionCount'] != '' || $impData[0]['ImpressionCount'] !=NULL ){
$impr_update = "UPDATE ClicksAndImpressions SET ImpressionCount = ". $impData[0]['ImpressionCount'] ." where Uid = 101642 and CampaignID =100 ;";
}else{
echo '----not Present';
}
//Impression count
foreach($impData as $key=>$data)
{
$data['ImpressionCount'];
$Impressionarr[] = $data;
}
//ACTION COUNT
$action_qry = "select count(*) as ActionCount from ClicksAndImpressions where Uid = 101617 and CampaignID =81 and Type = 'Action';";
$actionData = $this->getClicksAndImpressionsTable()->CustomQuery($action_qry);
if($actionData[0]['ActionCount'] != '' || $actionData[0]['ActionCount'] !=NULL ){
$action_update = "UPDATE ClicksAndImpressions SET ActionCount = ". $actionData[0]['ActionCount'] ." where Uid = 101617 and CampaignID =81 ;";
$actionData = $this->getClicksAndImpressionsTable()->CustomUpdate($action_update); //print_r($actionData);exit;
}else{
echo '----not Present';
}
//Action count
foreach($actionData as $key=>$data)
{
$data['ActionCount'];
$Actionarr[] = $data;
}
//Trying to combine the 3 arrays- but 2nd and 3rd not merging into 1st
$combine = array_merge($CampaignDetailsarr,$Impressionarr,$Actionarr);
1) Can the above duplicates - either in Update query or multiple for loops be avoided. if so how to optimize the above as per my conditions
ie) For
if( Uid = 123 for some campaignId = 11 and if type is 'Impression')
-> Update query for impression
else if(Uid = 123 for campaignId= 22 and if type = 'something else')
-> Update query for something else
2) I already have one array 1. I need to merge my 2 new arrays (Impressionarr[], Actionarr[]) into the 1st one, but below is how im getting.
Expected:
Coming as:
You could probably speed it up by creating a stored procedure in your database and calling that with the required data. From what I can see, most of the logic you have to do can be done in the stored procedure.
I need to create loop, get lowest ID value from mysql.
So I tried this script:
<?php
include "configuration.php"; // mysql konfiguration
$jungiam = mysql_connect("$db_host", "$db_user", "$db_pass");
mysql_select_db($db_name, $jungiam);
$darom = mysql_query("SELECT * from task where id = (
SELECT
MIN(id)
FROM
task)");
$rez = mysql_num_rows($darom);
while ($rez > 1) {
$row = mysql_fetch_array($darom);
echo $komanda = $row['komanda'];
mysql_query('DELETE * FROM task WHERE komanda = ' .$row['komanda'].'');
}
return true;
?>
I need to get lowest id and print to page $row['komanda'], after printing delete from that table where komanda = $row['komanda'] (printed text).
After deleting record, I need to do script from the start, so it will print text with lowest id from mysql and after that text will be deleted and proccess will start from start and will be repeating until all records in table 'task' will be deleted.
"SELECT * from task ORDER BY id ASC LIMIT 1;"
This will return the first element with the lowest ID.
I use this code to show category from database
$select_newscats = $mysqli->query("SELECT * FROM news_cats order by ord_show asc");
while ($rows_newscats = $select_newscats->fetch_array(MYSQL_ASSOC)){
$id_newscats = $rows_newscats ['id'];
$title_newscats = $rows_newscats ['title'];
$ord_show_newscats = $rows_newscats ['ord_show'];
$icon_newscats = $rows_newscats ['icon'];
$kind_newscats = $rows_newscats ['kind'];
$description_newscats = $rows_newscats ['description'];
//here is my data
}
i have in news table row for categoies it's name is cats and i insert data inside it like that 1,5,6,8
and i use this code to count news inside each cat
$select_newsnum = $mysqli->query("SELECT id FROM news where $id_newscats IN (cats)");
$rows_newsnum = $select_newsnum->fetch_array(MYSQL_ASSOC);
$num_newsnum = $select_newsnum->num_rows;
it gets only first value for example if i have this values 1,5,6,8 it gets only 1 the first value
I would do the counting in a single sql call, not with php logic and separate sql calls. For this I would join the 2 tables using left join and use a join condition instead of an in clause:
SELECT nc.id, nc.title, nc.ord_show, nc.icon, nc.king, nc.description, count(n.id) as newsnum
FROM news_cats nc
LEFT JOIN news n ON nc.id=n.cats
GROUP BY nc.id, nc.title, nc.ord_show, nc.icon, nc.king, nc.description
ORDER BY nc.ord_show asc
Obviously, make sure that the join condition is the right one. When you loop through the resultset, the number of news per category will be in the newsnum field.
$select_newsnum = $mysqli->query("SELECT id FROM news where $id_newscats IN (cats)");
$rows_newsnum = $select_newsnum->fetch_array(MYSQL_ASSOC);
$num_newsnum = $select_newsnum->num_rows;
Here $rows_newsnum will only return the first row in the database.
Fetch Array only returns one row at a time, and then moves the row pointer forward. For example the following code on the dataset you provided (1, 5, 6, 8).
$rows_newsnum = $select_newsnum->fetch_array(MYSQL_ASSOC);
echo $rows_newsnum["id"]; // Will print 1
$rows_newsnum = $select_newsnum->fetch_array(MYSQL_ASSOC);
echo $rows_newsnum["id"]; // Will print 5
What you need to do is move it into a while loop (like your first example) to get to access each row, like below:
while($row = $select_newsnum->fetch_array(MYSQL_ASSOC)) {
echo $rows_newsnum["id"] . ", ";
}
// Will produce:
// 1, 5, 6, 8,
If you just want to get a count
Your existing code should work fine. And you can omit the call to fetch_array.
$num_newsnum = $select_newsnum->num_rows;
echo $num_newsnum; // Will display 4
Read more about fetch_array on the PHP documentation:
http://php.net/manual/en/mysqli-result.fetch-array.php
Hope this helps.
I am trying to convert my not so well structured mysql article data to a better many-to-many structure.
basically I have on article table with fields 'article_id, title, author_1, author_2, author_3, ... , author_10' where article id is unique and the author fields hold full names.
What I need is a manay-to-many relationship where I end up with an article table of 'article_id, title' an intermediate table which holds 'article_id, author_id' and an author table which holds 'author_id, author_name'.
I know there must be a way to do this with a few lines of code. I have tried all day with puling the data out and trying to match arrays in php but getting nowhere.
Any help would be much appreciated.
It's pretty straightforward:
Outer loop selects all article rows from the existing table
For each of the author columns, insert a row into the authors table
After each insert, use mysql_insert_id() to get the ID of the inserted row, and insert the relationship into the article/author table.
-
$sql = "SELECT article_id, title, author_1, author_2, author_3, author_4, author_5, author_6, author_7, author_8, author_9, author_10 FROM articles";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result)) {
for ($i = 1; $i <= 10; $i++) {
if (!empty($row['author_' . $i])) {
$author = mysql_real_escape_string($row['author_' . $i]);
//check if author exists
$check = mysql_query("SELECT author_id FROM authors WHERE author_name = '$author'");
if (mysql_num_rows($check) > 0) {
$author_id = mysql_result($check,0);
} else {
mysql_query("INSERT INTO authors (author_name) VALUES ('$author')");
$author_id = mysql_insert_id();
}
mysql_query("INSERT INTO article_author (article_id, author_id) VALUES ({$row['article_id']}, $author_id)");
}
}
}