My problem seems like a rather small one to me, yet, I cannot figure out a proper solution.
The Setup: I have a table 'city_locations' with the columns 'country', 'city', 'longitude', 'latitude'. The countrys are given by 2-Letter ISO codes. I want them to be full names.
For this, I have imported the table 'countrycodes', containing only the columns 'name' and 'code'.
$namechange = $con->prepare("UPDATE city_locations SET country=? WHERE country=?");
$list = $con->prepare("SELECT name, code FROM countrycodes");
$list->execute();
$list->bind_result($name, $code);
$namechange->bind_param('ss', $name, $code);
while ($list->fetch()){
while ($namechange->execute()) {}
echo "$code is now $name <br>";
}
I succesfully retrieve all pairs in the (outer) while loop.
$namechange->execute(); however doesn't do anything - I tried it with and without the while loop, tried using LIMIT 0, 10000 in the query (though I'm not entirely sure I understand LIMIT right). With and without the while loop, the statement doesn't do anything. With LIMIT 0, 10000 the statement cannot be preapred properly (gives an error).
I also tried to bind the params new in every step of the while loop - didn't seem to do anything either.
When running the same command from my web interface, it works fine. However, in that case, I have to type all 200+ codes manually. Seems like a bit much work.
Thanks a lot for your help,
Kjeld.
EDIT: $con is of type mysqli.
$namechange = $con->prepare("UPDATE city_locations SET country=? WHERE country=?");
$list = $con->prepare("SELECT name, code FROM countrycodes");
$list->execute();
$list->bind_result($name, $code);
while ($list->fetch()){
$namechange->bind_param('ss', $name, $code);
$namechange->execute();
echo "$code is now $name <br>";
}
it will probably solve your problem.
Related
Im not trying to use a loop. I just one one value from one column from one row. I got what I want with the following code but there has to be an easier way using PDO.
try {
$conn = new PDO('mysql:host=localhost;dbname=advlou_test', 'advlou_wh', 'advlou_wh');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
$userid = 1;
$username = $conn->query("SELECT name FROM `login_users` WHERE username='$userid'");
$username2 = $username->fetch();
$username3 = $username2['name'];
echo $username3;
This just looks like too many lines to get one value from the database. :\
You can use fetchColumn():
$q= $conn->prepare("SELECT name FROM `login_users` WHERE username=?");
$q->execute([$userid]);
$username = $q->fetchColumn();
You could create a function for this and call that function each time you need a single value. For security reasons, avoid concatenating strings to form an SQL query. Instead, use prepared statements for the values and hardcode everything else in the SQL string. In order to get a certain column, just explicitly list it in your query. a fetchColumn() method also comes in handy for fetching a single value from the query
function getSingleValue($conn, $sql, $parameters)
{
$q = $conn->prepare($sql);
$q->execute($parameters);
return $q->fetchColumn();
}
Then you can simply do:
$name = getSingleValue($conn, "SELECT name FROM login_users WHERE id=?", [$userid]);
and it will get you the desired value.
So you need to create that function just once, but can reuse it for different queries.
This answer has been community edited addressing security concerns
Just like it's far too much work to have to get into your car, drive to the store, fight your way through the crowds, grab that jug of milk you need, then fight your way back home, just so you can have a milkshake.
All of those stages are necessary, and each subsequent step depends on the previous ones having been performed.
If you do this repeatedly, then by all means wrap a function around it so you can reuse it and reduce it down to a single getMyValue() call - but in the background all that code still must be present.
Okay, I have been tearing my hair (and beard) out at this one for a good hour or more now. I can't work out why it isn't working, particularly as it's exactly the same code I use elsewhere which does work.
$sql = "SELECT * FROM `aio_log` ORDER BY `log_timestamp` DESC LIMIT 10;"; // A 'WHERE' will be put in here
$logs = array();
$one_log = array();
if ($stmt = $mysqli->prepare($sql)) {
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($one_log['id'], $one_log['timestamp'], $one_log['headline'],
$one_log['text'], $one_log['link'], $one_log['font_awesome'],
$one_log['type']);
while ($stmt->fetch()) {
if ($one_log['link'] == "") $one_log['link'] = '#';
// print_r($one_log); shows the expected output of the database row.
$logs[] = $one_log;
//array_push($logs, $one_log); // gives the same - incorrect - response as the above line
}
}
print_r($logs); // Shows the right number of returned rows from the database, but all showing
// an identical content of the last database row returned.
Probably the only difference between this code and code I've used elsewhere is that this one doesn't have any binded parts of the SQL statement as it's a simple 'select everything no matter what' statement, but as the print_r($one_log) bit works fine, I cannot see this being the issue. The issue is obviously somewhere in the $logs[] = $one_log bit, but as I've used it elsewhere, and get exactly the same result using array_push, I'm at my wits end here!
Ideas folks?
This is very strange. The assignment
$logs[] = $one_log;
is supposed to make a copy of $one_log when it pushes it onto the array. But apparently this isn't interacting as expected with the fact that bind_param binds references to the variables -- when you fetch the new row, the references are apparently referring to the copy as well as the original. This is probably a weird consequence of the way that PHP uses copy-on-write; updating the reference seems not to be considered a write that triggers the copy.
I suggest you use normal variables instead of the $one_log array.
$stmt->bind_result($id, $timestamp, $headline, $text, $link, $font_awesome, $type);
and then in the fetch loop use:
$logs[] = array('id' => $id, 'timestamp' => $timestamp, 'headline' => $headline,
'text' => $text, 'link' => $link, 'font_awesome' => $font_awesome,
'type' => $type);
I am currently taking an IT course in which people can bring in their computer(s) and the class works on them to get experience. Right now, the instructor has the customers fill out a sheet of paper giving their name, phone number and the computer's issue(s). However, he would like to use a PHP page to allow the students or himself look back to see what this person's previous issues were (if any). I am using PDO and prepared statements to query the database, but I am having trouble figuring out how to get the number of records returned by the prepared statement. I've tried using stmt_num_rows, but it doesn't appear to be working. Here is the code I have so far:
$custID = $_GET["id"];
$compID = $_GET["compID"];
$stmtIssues = $db->prepare("SELECT IssueID, DateRequested, Issue, ActionsTaken FROM ISSUES WHERE ComputerID=:compID AND CustomerID=:custID ORDER BY DateRequested");
$stmtIssues->bindParam(":custID", $custID);
$stmtIssues->bindParam(":compID", $compID);
$stmtIssues->execute();
$numIssues = stmt_num_rows($stmtIssues);
Am I doing this right?
Any and all help is greatly appreciated.
Chris
You could do a few things:
Solution one, if you just want the count, let the database count for you:
$stmtIssues = $db->prepare("SELECT COUNT(IssueID) FROM ISSUES WHERE ComputerID=:compID AND CustomerID=:custID ORDER BY DateRequested");
$stmtIssues->bindParam(":custID", $custID);
$stmtIssues->bindParam(":compID", $compID);
$stmtIssues->execute();
$numIssues = $stmtIssues->fetchColumn();
Solution two, if you're going to display the results in addition to the count:
$stmtIssues = $db->prepare("SELECT IssueID, DateRequested, Issue, ActionsTaken FROM ISSUES WHERE ComputerID=:compID AND CustomerID=:custID ORDER BY DateRequested");
$stmtIssues->bindParam(":custID", $custID);
$stmtIssues->bindParam(":compID", $compID);
$stmtIssues->execute();
$rows = $db->fetchAll();
$numIssues = count($rows);
foreach ($rows as $row) {
echo $row['IssueID']; // you can add other columns and/or formatting here too.
}
Solution one is quicker and returns only the count. Solution two, on the other hand, returns all details you may want to display.
I´m very new to PDO. I just wonder what´s the best way to get the result when the data insert to the database comletely. I´m looking around in googl. seems like it´s flexible. That makes me wonder what is correct and what is incorrrect way.
Let see example:
$sql = $conn->prepare("INSERT INTO tb_user(user_name, user_email) VALUES(:user_name,:user_email);
$sql->execute(array(':user_name'=>$user_name, ':user_email'=>$user_email));
$affected_rows = $sql->rowCount();
From this script I want to get result if the data is finish to be insert in database.
If it done-->I will echo it like "complete" and send it back to ajax or etc...
I have tried :
if($affected_rows){
echo"YEZZ!! complete";
}
And
$all = $slq->fetchAll();
if(count($all)) {
echo"YEZZ!! complete";
}
And
if ($sql->execute){
echo"YEZZ!! complete";
//this one i know it will double insert data to database because I called it twice//
But I still want to know when can I use this method
And maybe more ways out there which make me crazy and want to know what is the best way to get result if the thing is done:
AFter insert, after delete, after update these 3 statements is the most important to know each.
Any suggestions could be wonderful !
}
}
you could do:
$id = $conn->lastInsertId('IDCOLUMN');
and then execute a query and search for the id
$stmt = $conn->prepare("SELECT * FROM tb_user WHERE IDCOLUMN = :id");
$stmt->execute(array("id", $id);
if($stmt->rowCount() > 0) {
$result = $stmt->fetch(PDO::FETCH_ASSOC);
}
the result variable will contain your last inserted record
Yes, your approach with rowCount() is a right one. Stick with it.
I am completely stumped. Here is my php (CodeIgniter) code:
function mod()
{
$uid = $this->session->userdata('uid');
$pid = $this->input->post('pid');
if ($this->_verify($uid,$pid))
{
$name = $this->input->post('name');
$price = $this->input->post('price');
$curr = $this->input->post('curr');
$url = $this->input->post('url');
$query = $this->db->query("UPDATE items SET
name=".$this->db->escape($name).",
price=".$this->db->escape($price).",
currency=".$this->db->escape($curr),",
url=".$this->db->escape($url)."
WHERE pid=".$this->db->escape($pid)." LIMIT 1");
}
header('location: '.$this->session->userdata('current'));
}
The purpose of this code is to modify the properties (name, price, currency, url) of a row in the 'items' table (priary key is pid). However, for some reason, allowing this function to run once modifies the name, price, currency and url of ALL entries in the table, regardless of their pid and of the LIMIT 1 thing I tacked on the end of the query. It's as if the last line of the query is being completely ignored.
As if this wasn't strange enough, I replaced "$query = $this->db->query(" with an "echo" to see the SQL query being run, and it outputs a query much like I would expect:
UPDATE items
SET name = 'newname',
price = 'newprice',
currency = 'newcurrency',
url = 'newurl'
WHERE pid = '10'
LIMIT 1
Copy-pasting this into a MySQL window acts exactly as I want: it modifies the row with the selected pid.
What is going on here???
Now I feel stupid: all it took was seeing my code in a different font. My code has
currency=".$this->db->escape($curr),",
instead of
currency=".$this->db->escape($curr).",
The echoing made it work just fine because apparently you can give echo more than one string, comma separated, and it concatenates them
cries I spent hours on this
I know you answered your own question, but let me just add this to the pile: You're not leveraging CodeIgniter AT ALL in this sort of query - which if you used CI as it's intended, you wouldn't have had that typo. Your query should look like this (among other things):
$query = $this->db->update('items',
array('name' => $this->input->post('name'),
'price' => $this->input->post('price'),
'curr' => $this->input->post('curr')),
array('id' => $this->input->post('id')),
1);
By assembling the query string by hand, you're undoing what CI does for you. Only when you're using some complex JOIN statement should you be writing your own SQL in CI, and even then, you want to use the sprintf PHP function to make sure you're not introducing typos.