Convert Mysql procedure into PHP code - php

I have a stored procedure on my Mysql DB, but i need to change it to get it done by PHP.
I've been looking around here and i know that is possible to make a SP from PHP, but it requires Mysqli (i don't have it updated, and updating it is not possible for personal reasons) or at least that was the only way i found to do it (source).
So for me that only have Mysql, it's possible to do it from php? or should i just "translate" the procedure into PHP format? I mean not making a procedure but a function instead (php function), that actually do the same with PHP code (loops, selects, calls and so) but not storing the procedure on the DB.
This is my procedure
DELIMITER //
create procedure autor_products (in id int)
begin
update authors set authors_products=
(SELECT DISTINCT count(products_id)
FROM products
INNER JOIN authors_to_manufacturers as am ON am.manufacturers_id = products.manufacturers_id
WHERE authors_id = id)
WHERE manufacturers_id = id;
end
//
DELIMITER $$
CREATE PROCEDURE authors()
BEGIN
DECLARE a INT Default 0 ;
DECLARE manu_length int;
select max(manufacturers_id) into manu_length from authors;
simple_loop: LOOP
SET a=a+1;
call autor_products(a);
IF a >= manu_length THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
END $$
DELIMITER ;
commit;
I managed to do this, which is "working" for at least one update
<?php
require('includes/configure.php'); //To get the DB name, user and pass
require_once (DIR_FS_INC.'xtc_db_connect.inc.php'); //I use this to connect the DB
$conn = xtc_db_connect() or die('Unable to connect to database server!');
$manu_lenght="select max(manufacturers_id) from authors;";
for ($i = 0;$i<=$manu_lenght;$i++){ //"for" not in use nor not working if i replace 1 for $i
$update= " update authors set products_amount = (SELECT DISTINCT count(products_id)
FROM products
INNER JOIN authors_to_manufacturers as am ON am.manufacturers_id = products.manufacturers_id
WHERE authors_id = 1)
WHERE manufacturers_id = 1;";
} //will only update 1 author with authors_id = 1 so i needed to make a loop, but if i replace 1 for $i. it doesn't update at all
$retval = mysql_query( $update, $conn );
if(! $retval )
{
die('Could not update data: ' . mysql_error());
}
echo "Updated data successfully\n";
?>
How may i use the $i variable instead of a specific number? (so it would update all at once because of the loop)
Edit: My manu_lenght is not working (it doesn't show the result of the select) but i just changed that part into a number and it's still not working, any thoughts?
Edit 2: Why is this code not working? It works if it's only $a=1; but not if i loop or make a bucle of $a.
$a = 1;
do{
$update= " update authors set products_amount = (SELECT DISTINCT count(products_id)
FROM products
INNER JOIN authors_to_manufacturers as am ON am.manufacturers_id = products.manufacturers_id
WHERE authors_id =$a)
WHERE manufacturers_id =$a;";
echo $a;
$a++;
}
while($a <= 10);
What im doing wrong?

After several tries i got what i need.
This is my code:
<?php
require('includes/configure.php');
require_once (DIR_FS_INC.'xtc_db_connect.inc.php');
$conn = xtc_db_connect() or die('Unable to connect to database server!');
//getting the total amount of authors into $manu_lenght variable
$manu_lenght = mysql_query("select max(manufacturers_id) as sum from authors;" );
if(!$manu_lenght){
die("DB query failed : " . mysql_error());
$sum = "";
} //needed to fetch the result of the select query
while ( $result = mysql_fetch_assoc($manu_lenght)){
$sum = $result["sum"];
}
do{
$author_update= " update authors set products_amount = (SELECT DISTINCT count(products_id)
FROM products
INNER JOIN authors_to_manufacturers as am ON am.manufacturers_id = products.manufacturers_id
WHERE authors_id =$a)
WHERE manufacturers_id =$a;";
$a++;
//while was here, so that's why it wasn't working
$ret_author = mysql_query( $author_update, $conn );
}
while($a <= $sum); //now is correct, it sends the query now
if(!$ret_author )
{
die('Could not update data: ' . mysql_error());
}
echo "Updated authors successfully\n";
?>
What i was basically doing wrong is ending the loop too early, and not letting the mysql_query function send the query (update in this case)
Instead of calling the procedure, i did the procedure translation through PHP. Hope this is useful for anyone else.

Related

Commands out of sync in A correct code

I've the following query executed via PHP, it used to work like yesterday, and stopped working today, here's it :
SELECT
*,
(SELECT IF (pro.uid= '4342','True','False') FROM pro) AS 'uid'
FROM
Episodes, pro
ORDER BY
Episodes.id DESC
LIMIT 9
The '4342' is changed with GET param, I'm having the following error :
Commands out of sync; you can't run this command now
My PHP API is as the following ( snippets ) :
<?php
include_once "db_config.php";
DEFINE ('DB_HOST', $host);
DEFINE ('DB_USER', $user);
DEFINE ('DB_PASSWORD', $pass);
DEFINE ('DB_NAME', $database);
$mysqli = #($GLOBALS["___mysqli_ston"] = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD)) OR die ('Could not connect to MySQL');
#((bool)mysqli_query($GLOBALS["___mysqli_ston"], "USE " . constant('DB_NAME'))) OR die ('Could not select the database');
?>
<?php
if(isset($_GET['meaE'], $_GET['uid']))
{
$query="SELECT * , (SELECT IF (pro.uid= '".$_GET['uid']."','True','False') FROM pro ) AS 'uid' FROM Episodes,pro ORDER BY Episodes.id DESC LIMIT 9
";
$resouter = mysqli_query($GLOBALS["___mysqli_ston"], $query);
}
$set = array();
$total_records = mysqli_num_rows($resouter);
if($total_records >= 1){
while ($link = mysqli_fetch_array($resouter, MYSQLI_ASSOC)){
$set['APITest'][] = $link;
}
}
echo $val= str_replace('\\/', '/', json_encode($set));
?>
I want to have the following output :
TABLE A - TABLE B
ID NAME TEXT UID - Check_ID
The query I want :
Select * From Table A, Check if "134123123" is exists in B, if yes / no add a record for all the taken records from Table A with the value of checking (True/False) .
What's happening with #sagi query is :
There are 3 records in Table B, and 10 records in Table A, when the query is executed, the result is 30 records, each record in Table B has 10 records from Table A, and the "uid" record value is True where the uid is '134123123', and it's false where it's not '134123123' .
Your query seems wrong, I don't know how it worked yesterday, but right now your are cross joining with out a condition (could be correct but I doubt it) - that means each record in episodes will be joined to each record in pro . In addition, your subquery with the IF will return more then 1 record unless this table contains only 1 record (which again - I doubt it) .
Try this:
SELECT distinct t.*, IF (s.uid is null,'True','False') AS 'uid'
FROM Episodes t
Left JOIN pro s
ON(s.uid = '4342')
ORDER BY t.id DESC
LIMIT ?????
Try using a sub query instead of a join:
Select t.*,
Case when exists(select 1 from pro s where s.uid = '4342')
Then 'true' else 'false'
End as 'uid'
From episodes t
Order by t.id desc
Limit 9;

How to access the rows before and after a pivot row (can be any row) using a loop in a PHP script working on a mySQL database?

The following code queries the database for every row preceding the pivot row using 'for' loop in php script. Same is the case with querying all the folowing rows. This code is not optimized as everytime a new query is injected into sql. Is there any technique that can speed up the whole process? Is there any query in mysql that can solve the purpose and using which the loop can be bypassed?
while($speed < 3 && $found > 0)
{
$sub_query = "select * from sheet_17_43_2 where Generation = ". $found ."-1";
$res = mysql_query($sub_query);
if (!$res)
{
echo "Could not successfully run query ($sql) from DB: " . mysql_error();
exit;
}
if (mysql_num_rows($res) == 0)
{
echo "No rows found, nothing to print so am exiting";
exit;
}
$speed = mysql_fetch_assoc($res)["Speed"];
mysql_free_result($res);
$time++;
}
To compare the current value of a column (col) to the 'previous' value, do something like
SELECT t.col - #prev AS change_from_prev,
#prev := t.col
FROM
( SELECT #prev := 0 ) initializer
JOIN t
ORDER BY ...
The ORDER BY is important.

Can I change values in a SQL array in PHP and resort?

I have a SELECT statement that pulls a limited number of items based on the value of one of the fields. (ie ORDER BY rate LIMIT 15).
However, I need to do some comparisons that and change the value of rate, and subsequently could alter the results that I want.
I could pull everything (without the LIMIT), alter the rate, re-sort, and then just process the number that I need. However, I don't know if it's possible to alter values in a php result array. I'm using:
$query_raw = "SELECT dl.dragon_list_id, dl.dragon_id, dl.dragon_name, dl.dragon_level, d.type, d.opposite, d.image, dr.dragon_earn_rate
FROM dragon_list dl
LEFT JOIN dragons d ON d.dragon_id = dl.dragon_id
LEFT JOIN dragon_rates dr ON dr.dragon_id = dl.dragon_id
AND dr.dragon_level = dl.dragon_level
WHERE dl.dragon_id IN (
SELECT dragon_id
FROM dragon_elements
WHERE element_id = 3
)
AND dl.dragon_list_id NOT IN (
SELECT dh.dragon_list_id
FROM dragon_to_habitat dh, dragon_list dl
WHERE dl.user_id = 1
AND dh.dragon_list_id = dl.dragon_list_id
AND dl.is_deleted = 0
)
AND dl.user_id = " . $userid . "
AND dl.is_deleted = 0
ORDER BY dr.dragon_earn_rate DESC, dl.dragon_name
LIMIT 15;";
$query = mysqli_query($link, $query_raw);
if (!$query) {
echo "DB Error, could not query the database\n";
echo 'MySQL Error: ' . mysqli_error($link);
exit;
}
$d = mysqli_fetch_array($d_query);
Well, after a lot of research and some trial and error I found my answers....
Yes, I CAN alter the result rows using something like:
$result['field'] = $newvalue;
I also learned I could reset the pointer by using:
mysqli_data_seek($d_query,0);
However, when I reset the counter, I lost the changes I made. So ultimately, I'm still a little stuck, but individually I had the answers.

Fetching data with PDO

I'm introducing myself to PDO and i'm trying to fetch data with it. I've done this before, but now i'm getting errors all the time. I've been through this for some hours and didn't find a mistake. If someone could help: my code is:
$tabelas_intervalos_afunda = ($con -> query('CREATE TABLE IF NOT EXISTS afunda_$a
SELECT (L1_forma_tensao_max + L1_forma_tensao_min)/2 as L1_forma_tensao, (L2_forma_tensao_max + L2_forma_tensao_min)/2 as L2_forma_tensao, (L3_forma_tensao_max + L3_forma_tensao_min)/2 as L3_forma_tensao
FROM afundamento
WHERE id > $prevNum AND id < $a');
while($row=$tabelas_intervalos_afunda->fetch(PDO::FETCH_ASSOC))
{
$array_forma_onda_fase1_afund[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund[] = $row['L3_forma_tensao'];
}
My problem is that when i var_dump($array_forma_onda_fase1_afund), it returns me "Undefined variable $array_forma_onda_fase1_afund
NULL
Some additional info: $a is changed always when the loop condition is satisfied. The table afunda_$a is being created as expected, table afundamento exists normally.
Would appreciate any help/suggestions.
You are running a create table statement, which returns no rows. Then running fetch on the result, which doesn't enter the while statement. Hence $array_forma_onda_fase1_afund is never defined.
If you want the records you are inserting, you can select them out of the new table or run the original select query. E.g.:
$con->query('CREATE TABLE IF NOT EXISTS afunda_$a
SELECT (L1_forma_tensao_max + L1_forma_tensao_min)/2 as L1_forma_tensao, (L2_forma_tensao_max + L2_forma_tensao_min)/2 as L2_forma_tensao, (L3_forma_tensao_max + L3_forma_tensao_min)/2 as L3_forma_tensao
FROM afundamento
WHERE id > $prevNum AND id < $a');
$tabelas_intervalos_afunda = $con->query("SELECT * FROM afunda_$a");
while($row=$tabelas_intervalos_afunda->fetch(PDO::FETCH_ASSOC))
{
$array_forma_onda_fase1_afund[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund[] = $row['L3_forma_tensao'];
}

Commands out of sync while calling stored procedure Mysql

i have two store procedures, i needed to page the record (say select every next n records) to the first one which select all matching records is.
CREATE PROCEDURE `trans_all`(IN varphone VARCHAR(15))
BEGIN
Select
loans.amt,
loans.date,
loans.pay_period,
borrower.phone As borrower_phone,
borrower.name As borrower_name,
lender.phone As lender_phone,
lender.name As lender_name,
From
loans Left Join
users borrower On borrower.id = loans.borrower_id Left Join
users lender On lender.id = loans.lender_id
Where
(lender.phone = varphone) or (borrower.phone = varphone);
END
i then get the count in php ;like this
$result = $mysqli->query(sprintf("call trans_all('%s')",$phone));
$num_recs = $result->num_rows;
then i needed to select precise records to i do do this
$result = $mysqli->query(sprintf("call trans_history('%s','%s','%s')",$phone,$start,$limit));
$row = $result->fetch_assoc(); // this like gives the error Commands out of sync; you can't run this command now
the second stored procedure is
CREATE PROCEDURE `trans_history`(IN varphone VARCHAR(15), IN page INT, IN items INT)
BEGIN
Select
loans.amt,
loans.date,
loans.pay_period,
borrower.phone As borrower_phone,
borrower.name As borrower_name,
lender.phone As lender_phone,
lender.name As lender_name,
From
loans Left Join
users borrower On borrower.id = loans.borrower_id Left Join
users lender On lender.id = loans.lender_id
Where
(lender.phone = varphone) or (borrower.phone = varphone) LIMIT page , items;
END
what could be cause this error?
SPs return second resultset which contains the status. You need to use next_result() before you make subsequent queries.
$result = $mysqli->query(sprintf("call trans_all('%s')",$phone));
$num_recs = $result->num_rows;
$result->close();
$mysqli->next_result(); // <- you need this before you make another query
//Then make call second SP
$result = $mysqli->query(sprintf("call trans_history('%s','%s','%s')",$phone,$start,$limit));
$row = $result->fetch_assoc();
$result->close();
$mysqli->next_result();

Categories