Am getting an error of prepared statement "my_query7" already exists, i call this function each time a user tries to update table leader_info in the database, i have gone through the documentation for pg_prepare and i don't understand what is meant by it should only be run once. code snippets will be of help. Thanks.
function add_leader_country($user_id,$l_country)
{
global $connection;
$query = pg_prepare($connection,"my_query7","update leader_info set l_country = $1 where user_id = $2 and status < 9");
$result = pg_execute($connection,"my_query7",array($l_country,$user_id));
if(!$result)
{
echo pg_last_error($connection);
}
else
{
echo "Records created successfully\n";
}
$row = pg_affected_rows($result);
return $row;
}
Prepare execute does not permit duplicate naming, so that is your error.
A query should only be prepared once, for example, in a cycle for the preparation state must be set out of the for and its execution in the for.
$result=$pg_prepare($connection,"my_query7",$query);
for($id=1;$id<3;$id++){
$result=pg_execute($connection,"my_query7",array($l_country,$user_id));
...
}
In your case using a functio that use the prepare and execute multiple times it's a problem.
What are you trying to accomplish with this function dispatches more code like where you are calling the function. This way I might be able to help you.
If you want to use functions I would use this method
Exemple from https://secure.php.net
<?php
function requestToDB($connection,$request){
if(!$result=pg_query($connection,$request)){
return False;
}
$combined=array();
while ($row = pg_fetch_assoc($result)) {
$combined[]=$row;
}
return $combined;
}
?>
<?php
$conn = pg_pconnect("dbname=mydatabase");
$results=requestToDB($connect,"select * from mytable");
//You can now access a "cell" of your table like this:
$rownumber=0;
$columname="mycolumn";
$mycell=$results[$rownumber][$columname];
var_dump($mycell);
If you whant to use preaper and execute functions try to create a function that creates the preparations only once in a session. Do not forget to give different names so that the same error does not occur. I tried to find something of the genre and did not find. If you find a form presented here for others to learn. If in the meantime I find a way I present it.
Related
I have a function to process info from a database. This is called multiple times in a page. And I don't want to query the database every time. So I put the query outside. If I do that, the function doesn't work. I know this can be done because, there was a similar question somewhere in SO. But that addressed a different situation. I don't know what is wrong here. Any help will be greatly appreciated.
If I put all this code into a separate test file including the conn file and query, it works. But in my main page, where I have the functions.php included first, then conn.php and then the query and then the display code called by js fadein event, the $result refuses to work inside the function
EDIT : This code has been cleaned up as per comments received (globals replaced with variables passed to the function and variable names rationalised)
function total($item,$result,$val){
global $totRate;
while($getRates=$result->fetch_assoc()){
$gotItem= strtolower(preg_replace('/[^(\x20-\x7F)]*/',"",$getRates['item']));
$gotItem=str_replace(array("_"," ","/"),"",$gotItem);
if($item==$gotItem){
$rate= $getRates['rate'];
$totRate=$val*$rate;
return $totRate;
}
}
}
The Result Call PHP file
$query = "SELECT * FROM rates ORDER BY item";
$result = $orderdb->query($query)
if (isset($_POST[$itemname]) && !empty($_POST[$itemname])) {
$val=$_POST[$itemname];
total($itemname);
echo $totprate;
} else {
echo "0";
}
I am writing this with the assumption that your SQL is working but are having problems displaying what you want - this may help. The code below saves your $result variable from your query and then passes it into the total function as a second parameter. Previously you were returning $totprate from total but you were not saving it anywhere - it is now saved to the $totprate variable.
Note: I cannot see $orderdb anywhere in your code, I'm assuming you have that in your file and that it is working.
function total($item, $result){
global $val;
global $pid;
global $pitem;
global $prate;
global $totprate;
global $gotitem;
global $getratess;
// global variable for $result removed so it doesn't overwrite variable passed to function
while($getratess=$result->fetch_assoc()){
$gotitem= strtolower(preg_replace('/[^(\x20-\x7F)]*/',"",$getratess['item']));
$gotitem=str_replace(array("_"," ","/"),"",$gotitem);
if ($item==$gotitem) {
$pid=$getratess['id'];
$pitem= $getratess['item'];
$prate= $getratess['rate'];
$totprate=$val*$prate;
return $totprate;
}
}
}
$query = "SELECT * FROM rates ORDER BY item";
$result = $orderdb->query($query);
if (isset($_POST[$itemname]) && !empty($_POST[$itemname])) {
$val=$_POST[$itemname];
$totprate = total($val, $result); // pass itemname as first parameter and result array as second parameter and save it to the $totprate variable
echo $totprate;
} else {
echo "0";
}
Let me know if this helps.
This is the one thing that I am trying absolutely first time. I have made few websites in PHP and MySQL as DB but never used functions to get data from database.
But here is the thing that I am trying all new now as now I want to achieve reusability for a bog project. I wanted to get the order details from DB (i.e. MySQL) through PHP Function. I am bit confused that how to print values returned by a PHP function.
Function wrote by me is as below:
function _orderdetails(){
$sql = "Select * from orders WHERE 1";
$result = DB::instance()->prepare($sql)->execute()->fetchAll();
return $result;
}
Please let me know how i can print these values and value returned by above function is an array.
I tried by calling function directly through print_r(_orderdetails());
Please let me know:
Efficient way of iterating through this function to Print Values.
Is there any other approach that can be better worked upon?
You cannot chain fetchAll() to execute() like this.
Besides, for a query that takes no parameters, there is no point in using execute(). So change your function like this
function _orderdetails(){
$sql = "Select * from orders WHERE 1";
return DB::instance()->query($sql)->fetchAll();
}
and so you'll be able to iterate results the most natural way
foreach (_orderdetails() as $order) {
echo $order['id'] . '<br />';
}
You can also use ->fetch();
Instead of ->fetchAll();
There some other functions that also work as a worker to iterate through the next row in the table.
You can check PDO for more functions at:
http://php.net/manual/en/book.pdo.php
In your PHP code that will call this function use the following
print_r(_orderdetails());
//to get all the result set... I mean all the values coming from this function.
You can also use the function and use -> after the function call, then put the variable name as follows:
To iterate through the values of this function:
$value_arr = _orderdetails();
foreach ($valur_arr as $value) {
echo $value . '<br />';
}
This way you will echo 1 column from the database table you are using.
Recently I seem to be writing nearly the same sql statements and I have to use PHP for looping and error reporting, so I'm trying to write something general that will shorten my code extensively. I'm still learning programming.
I don't know if I need to use classes or what, but here's an example of what I'm trying to do.
/////////q = query, f = fetch type(loop or single object), r = row;
function dbQuery($q, $f, $r){
global $con;
$query = mysqli_query($con, $q) or die(mysqli_error($con));
if ($f = 'loop'){
while($row = mysqli_fetch_array($query)){
echo $r;
}
} else if ($f='single'){
$row = mysqli_fetch_array($query);
echo $r;
}
///////////or prepared statements//////////
}
dbQuery("SELECT * FROM music WHERE perms = 'a' limit 50", $f='loop', $r="<div>".$row['title']."</div>"
);
I want something like the following, I know its not write but I want to be able to have the function above return row results to the function's arg.
dbQuery($f='loop'){ /////////// I really don't know the corrent way for this////
$q= "SELECT * FROM music WHERE perms = 'a' limit 50";
$r="<div>".$row['title']."</div>";
////////and breaking out of php////
?>
<section><?php echo $row['duration']; ?></section>
<?php
}
Please do recommend materials I can check out.
I will recommend you to use some framework like Laravel or some query builder class. There are tons of them. If for some reason, you will like to create your own, please do not use mysql function, since is deprecated. Personally, I will prefer PDO over mysqli (this is just a preference) make sure to prepare statements. Check this link out, it will help you with your project
http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
Good luck with your project.
So let me explain my problem, lets assume that I run query like so:
$myquery = sql_query("SELECT name FROM table WHERE name='example' LIMIT 0,1");
Now.. I want to store the retrieved name into a variable so I would do something like this:
while ($myrow = sql_fetch_assoc($myquery)) {
transfer_row($myrow);
print"Name: $row_name";
}
$stored_name = $row_name;
NOTE: transfer_row() is just a function I wrote that takes $myrow['name'] and stores it in $row_name, for easier reference
Now, all is fine at this stage, here is where it gets interesting. Note that at this stage I still have a name assigned to $row_name. Further down the page I run another query to retrieve some other information from the table, and one of the things I need to retrieve is a list of names again, so I would simply run this query:
$myquery = sql_query("SELECT name, year FROM table WHERE DESC LIMIT 0,10");
while ($myrow = sql_fetch_assoc($myquery)) {
transfer_row($myrow);
$year = $row_year;
$link = "/$year";
print "<li style=\"margin-bottom: 6px;\">$row_name\n";
}
Now, I want to write an if statement that executes something if the $row_name from this query matches the $row_name from the old query, this is why we stored the first $row_name inside the variable.
if ($row_name == $stored_name){
// execute code
}
However as most of you know, this WONT work, the reason is, it simply takes $stored_name again and puts the new $row_name into $stored_name, so therefore the value of the first $row_name is lost, now it is crucial for my application that I access the first $row_name and compare it AFTER the second query has been run, what can I do here people? if nothing can be done what is an alternative to achieving something like this.
Thanks.
EDIT, MY transfer_row() function:
function transfer_row($myrow) {
global $GLOBALS;
if(is_array($myrow)) {
foreach ($myrow as $key=>$value) {
$key=str_replace(":","",$key);
$GLOBALS["row_$key"] = $value;
}
}
}
Without you posting the code for the function transfer_row, we won't be able to give you an answer that exactly matches what you request, but I can give you an answer that will solve the problem at hand.
When matching to check if the names are the same, you can modify the if statement to the following.
if ($row_name == $myrow['name']){
// execute code
}
What I suggest you do though, but since I don't have the code to the transfer_row function, is to pass a second variable to that function. The second variable will be a prefix for the variable name, so you can have unique values stored and saved.
Refrain from using the transfor_row function in the second call so your comparison becomes:
if ($myrow['name'] == $row_name)
If you need to use this function, you could do an assignment before the second database call:
$stored_name = $row_name;
...
transfer_row($myrow);
In your first query you are selecting the name field WHERE name='example' , Why are you quering then? You already have what you want.
Your are querying like:
Hey? roll no 21 what is your roll no?
So perform the second query only and use the if condition as :
if ($row_name == 'example'){
// execute code
}
Does it make sense?
Update
//How about using prefix while storing the values in `$GLOBAL` ??
transfer_row($myrow, 'old_'); //for the first query
transfer_row($myrow, 'new_'); //for the second query
function transfer_row($myrow, $prefix) {
global $GLOBALS;
if(is_array($myrow)) {
foreach ($myrow as $key=>$value) {
$key=str_replace(":","",$key);
$GLOBALS["$prefix"."row_$key"] = $value;
}
}
}
//Now compare as
if ($new_row_name == $old_row_name){
// execute code
}
//You'll not need `$stored_name = $row_name;` any more
I have this function:
function myFunc()
{
$conn=new mysqli('localhost','root','','myDb');
$conn->query('BEGIN');
$query="SELECT events_participants.userid,(SELECT COUNT(*) FROM events_participants WHERE events_participants.eventid=events.id FOR UPDATE) AS totRep FROM events INNER JOIN events_participants ON events_participants.eventid=events.id WHERE events.isConfirmed=3 AND reputationsUpdated=0";
$result=$conn->query($query);
if($result!==FALSE)
{
while(($row=$result->fetch_assoc())!==NULL)
{
$query="UPDATE users SET reputation=reputation+".$row['totRep'].",presences=presences+1 WHERE id=".$row['userid'];
$result=$conn->query($query);
if($result==FALSE)
{
$conn->query('ROLLBACK');
throw new DatabaseErrorException();
}
}
$query="UPDATE events SET reputationsUpdated=1 WHERE isConfirmed=3 AND reputationsUpdated=0";
$result=$conn->query($query);
if($result!==false)
$conn->query('COMMIT');
else
$conn->query('ROLLBACK');
throw new DatabaseErrorException();
}
else
{
throw new DatabaseErrorException();
}
}
myFunc();
If i test this it tells me:
Call to a member function fetch_assoc() on a non-object..on the line where is the while loop.
But the fetch_assoc method over there actually populated my $row array (i tested echoing out $row['totRep']..so the problem is not in the query..
even if I test the same query in phpmyadmin it actually returns two rows..
where is the error?
what am I missing??
thank you again guys!
You are rewriting your $result variable numerous times.
You have to rename it.
If a variable going to be used further in the script (like $result one) it shouldn't be rewritten.
However, if it's one-time used variable, like $query one, it's possible to keep the same name for readability.
if($result) is the correct way.
if($result!=false) is also correct.
if($result!==false) is WRONG.