Can anyone let me know why this PDO Statement won't work inside the for loop? I'm trying to add one to the position for each new entry into the database. for some reason this is breaking. Any ideas on why?
Edit
Please ignore the next position, etc. For other reasons the gp_position can not be AUTO_INCREMENT and next position won't always start at 1. Please focus on why this PDO Statement won't work inside the loop.
$nextPosition = 1;
$imgID = 1;
$indb_gridID = 1;
$timesToRepeat = 33;
$indb_mem_id = ($this->user->is_logged_in()) ? $this->user->info['id'] : 1;
for($i=1; $i<=$timesToRepeat; $i++) {
// now add the image to the grid positions
$stmt = dbpdo::$conn->prepare("INSERT INTO grid_positions SET
gp_mem_id = :memID,
gp_g_id = :gridID,
gp_img_id = :imgID,
gp_position = :position");
$stmt->bindParam(':memID', $indb_mem_id, PDO::PARAM_INT);
$stmt->bindParam(':gridID', $indb_gridID, PDO::PARAM_INT);
$stmt->bindParam(':imgID', $imgID, PDO::PARAM_INT);
$stmt->bindParam(':position', $nextPosition, PDO::PARAM_INT);
$stmt->execute();
$nextPosition++;
}
Try this refactored code:
$nextPosition = 1;
$imgID = 1;
$indb_gridID = 1;
$timesToRepeat = 33;
$indb_mem_id = ($this->user->is_logged_in()) ? $this->user->info['id'] : 1;
// prepare the statement once:
$stmt = dbpdo::$conn->prepare("INSERT INTO grid_positions SET
gp_mem_id = :memID,
gp_g_id = :gridID,
gp_img_id = :imgID,
gp_position = :position");
$stmt->bindParam(':memID', $indb_mem_id, PDO::PARAM_INT);
$stmt->bindParam(':gridID', $indb_gridID, PDO::PARAM_INT);
$stmt->bindParam(':imgID', $imgID, PDO::PARAM_INT);
$stmt->bindParam(':position', $nextPosition, PDO::PARAM_INT);
for($i=1; $i<=$timesToRepeat; $i++) {
// exec statement with current values:
$stmt->execute();
$nextPosition++;
}
Related
This code is supposed to insert 100 rows into the DB.
Yet when I run it, it loops only once, inserts one row and stops.
I replaced the function call with :
echo $keywords[4].'<br>';
It works perfectly. with no probleb
What is missing so that it will insert all rows into DB?
what should I change q add so that the code will insert all rows in the file
Here is the loop code:
do{
//Insert row content into array.
$keywords = preg_split("#\<(.*?)\>#", $row);
//Insert relevant data into DB
add_data($keywords);
}
else{
// If row is irrelevant - continue to next row
continue;
}
}while (strpos($row, 'Closed P/L') != true);
Here is the function
function add_data($keywords)
{
global $db;
$ticket =$keywords[2];
$o_time = $keywords[4];
$type = $keywords[6];
$size = $keywords[8];
$item = substr($keywords[10], 0, -1);
$o_price = $keywords[12];
$s_l = $keywords[14];
$t_p = $keywords[16];
$c_time = $keywords[18];
$c_price = $keywords[20];
$profit = $keywords[28];
try
{
$sql = "
INSERT INTO `data`
(ticket, o_time, type, size, item, o_price, s_l, t_p, c_time, c_price, profit)
VALUES
(:ticket, :o_time, :type, :size, :item, :o_price, :s_l, :t_p, :c_time, :c_price, :profit)";
$stmt = $db->prepare($sql);
$stmt->bindParam('ticket', $ticket, PDO::PARAM_STR);
$stmt->bindParam('o_time', $o_time, PDO::PARAM_STR);
$stmt->bindParam('type', $type, PDO::PARAM_STR);
$stmt->bindParam('size', $size, PDO::PARAM_STR);
$stmt->bindParam('item', $item, PDO::PARAM_STR);
$stmt->bindParam('o_price', $o_price, PDO::PARAM_STR);
$stmt->bindParam('s_l', $s_l, PDO::PARAM_STR);
$stmt->bindParam('t_p', $t_p, PDO::PARAM_STR);
$stmt->bindParam('c_time', $c_time, PDO::PARAM_STR);
$stmt->bindParam('c_price', $c_price, PDO::PARAM_STR);
$stmt->bindParam('profit', $profit, PDO::PARAM_STR);
$stmt->execute();
//return true;
}
catch(Exception $e)
{
return false;
echo 'something is wrong. Here is the system\'s message:<br>'.$e;
}
}
The following PHP code, which is a subset of DataTables.net Server Side processing using SQLite3 always generates error Unable to execute statement: datatype mismatch
// Handle Server Side ajax request from DataTables in browser
// init database
$db = new SQLite3('appname.SQLite3.db');
// parse request parameters
$start = (int) $_GET['start'];
$length = (int) $_GET['length'];
// Prepare statement
$sql = "
SELECT
personId, personName
FROM person
LIMIT :start, :length
";
$stmt = $db->prepare($sql);
$stmt->bindParam(':start', $start);
$stmt->bindParam(':length', $length);
// execute statement
$result = $stmt->execute();
$response['data'] = [];
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$response['data'][] = $row;
}
// use same prepared statement to count not paged number of records
$start = 0;
$length = PHP_INT_MAX;
$result = $stmt->execute(); // <---- fails here with datatype mismatch error -------
$recordsTotal = 0;
while ($result->fetchArray(SQLITE3_NUM)) {
$recordsTotal++;
}
$response['draw'] = (int) $_GET['draw']; // used by DataTables to synchronize request and reply
$response['recordsTotal'] = $recordsTotal;
header('Content-Type: application/json');
echo json_encode($rsp);
exit;
For more information about DataTables.net Server Side processing, see
https://datatables.net/manual/server-side
SQLite3Stmt::reset is required between the two execute() invocations.
public bool SQLite3Stmt::reset ( void )
Resets the prepared statement to its state prior to execution. All bindings remain intact after reset.
$stmt = $db->prepare($sql);
$stmt->bindParam(':start', $start);
$stmt->bindParam(':length', $length);
$rslt = $stmt->execute();
// ...
$recordsTotal = 0;
$start = 1;
$length = PHP_INT_MAX;
$stmt->reset(); // was missing statement
$rslt = $stmt->execute(); // no error any more
This question already has an answer here:
$stmt->num_rows returning 0 even after calling store_result
(1 answer)
Closed 9 years ago.
i am just trying to learn prepared statement and i am following the PHP manual to guide me through, i have checked the answers regarding this problem on stackoverflow but, i can't find any solutions, the $stmt->num_rows always ( Return 0 )
there is a post on stackoverflow discussed the problem and they advised to use
$stmt->store_result() just before the $stmt-num_rows, but the $stmt->num_rows return 0
some one please can tell me what i am doing wrong here.... i am just sick of the procedural style coding and i want to enhance my skills with prepared statement
here is the function down below
function get_all()
{
// ** Initializing the Connection
$mysqli = Connect();
$sql = ( ' SELECT * FROM `users` ' );
$stmt = $mysqli->prepare($sql);
$stmt->execute();
$res = $stmt->get_result();
echo $num_count = $stmt->num_rows();
$user = array();
for ($counter = 0; $row = $res->fetch_assoc(); $counter++)
{
$user[$counter] = $row;
}
return $user;
}
// This is the second update
function get_all()
{
// ** Initializing the Connection
$mysqli = Connect();
$sql = ( ' SELECT * FROM `users` ' );
$stmt = $mysqli->prepare($sql);
$stmt->execute();
$res = $stmt->get_result();
echo $num_count = $stmt->num_rows;
$user = array();
while($row = $res->fetch_assoc())
{
$user[] = $row;
}
return $user;
}
// third update
function get_alll()
{
// ** Initializing the Connection
$mysqli = Connect();
// no need to use * character,
// need to write query this way
$sql = ( ' SELECT `id`,`fname`,`lname`,`uname`,`email` FROM `users` ' );
$stmt = $mysqli->prepare($sql);
// here need to use bind param
$stmt->bind_result( $id, $fname, $lname, $uname, $email);
$stmt->execute();
// it's important to store the result
// before using num rows
$res = $stmt->store_result();
echo $num_count = $stmt->num_rows;
//
while($stmt->fetch())
{
echo $fname;
}
}
num_rows is a property, not a method, try with $stmt->num_rows without brackets
I am creating a random user ID, but I would like to check if the ID already has been used (very unlikely but the chances are there), but somehow this doesn't work. When I look in the database, there is no random character string in the account_id field. Do I call the functions in a wrong way?
function genRandomString() {
$length = 40;
$characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters))];
}
return $string;
}
function createID() {
$cl_id = 'h_u_'.genRandomString();
}
createID();
$sql_query="SELECT * FROM accounts WHERE account_id = :cl_id";
$statement = $conn->prepare($sql_query);
$statement->bindParam(':cl_id', $cl_id, PDO::PARAM_STR);
if ($statement->execute() && $row = $statement->fetch())
{
createID();
}
$conn->exec("INSERT INTO accounts SET
account_id='$cl_id' ,
name='$_POST[name]' ,
email='$_POST[email]' ");
$cl_id is a local variable in createID() function , you need to return your value to your global code ...
function createID() {
return $cl_id = 'h_u_'.genRandomString();
}
you need to check $id in the main code
$id = createID();
$sql_query="SELECT * FROM accounts WHERE account_id = '".$cl_id."'";
$statement = $conn->prepare($sql_query);
1 . You missed to return $c_id in createID(). Change it to:
function createID() {
return 'h_u_'.genRandomString();
}
$cl_id = createID();
2 . You could use good old uniqid() instead of your custom genRandomString().
This would lead to something simpler like:
function createID() {
return 'h_u_'.uniqid();
}
$cl_id = createID();
3 . You'll have to change the if in the database related code to a loop (have a look at my example below)
4 . Your insert query uses unverified $_POST vars. This is highly prone to SQL Injections. If your Database library supports server side prepared statements you should use them and you can feel secure because data is being kept separate from the query syntax. If you are using PHP with MySQL this is the case.
If you are not using server side prepared statements you should escape any $_POST data used in the query by using mysql_real_escape_string() or something like this. In the following example I'm assuming that you are using PHP with MySQL and thatswhy I use a prepared statement.
Taking all this in account may result in a finished script like this:
$sql_query="SELECT * FROM accounts WHERE account_id = :cl_id";
$statement = $conn->prepare($sql_query);
$maxtries = 3; // how many tries to generate a unique id?
for($i = 0; $i < $maxtries; $i++) {
$cl_id = uniqid(); // create a 'unique' id
$statement->bindParam(':cl_id', $cl_id, PDO::PARAM_STR);
if (!$statement->execute()) {
die('db error');
}
$row = $statement->fetch();
if($row) {
continue;
}
break;
}
// if a unique id couldn't get generated even
// after maxtries, then pigs can fly too :)
if($i === $maxtries) {
die('maximum number of tries reached. pigs can fly!');
}
// You should use a prepared statement for the insert to prevent from
// SQL injections as you pass $_POST vars to the query. You should further
// consider to validate email address and the name!
$name = $_POST['name'];
$email = $_POST['email'];
$insert_query = '
INSERT INTO accounts SET
account_id = :account_id,
name = :name,
email = :email';
$insert_statement = $conn->prepare($insert_query);
$insert_statement->bindParam(':account_id', $cl_id, PDO::PARAM_STR);
$insert_statement->bindParam(':name', $name, PDO::PARAM_STR);
$insert_statement->bindParam(':account_id', $email, PDO::PARAM_STR);
if (!$insert_statement->execute()) {
die('db error');
}
I'm working with a SQL Server stored procedure that returns error codes; here is a very simple snippet of the SP.
DECLARE #ret int
BEGIN
SET #ret = 1
RETURN #ret
END
I can get the return value with the mssql extension using:
mssql_bind($proc, "RETVAL", &$return, SQLINT2);
However, I can't figure out how to access the return value in PDO; I'd prefer not to use an OUT parameter, as alot of these Stored Procedures have already been written. Here is an example of how I am currently calling the procedure in PHP.
$stmt = $this->db->prepare("EXECUTE usp_myproc ?, ?");
$stmt->bindParam(1, 'mystr', PDO::PARAM_STR);
$stmt->bindParam(2, 'mystr2', PDO::PARAM_STR);
$rs = $stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
Check out MSDN for info on how to correctly bind to this type of call
Your PHP code should probably be tweaked to look more like this. This may only work if you're calling through ODBC, which is honestly the strongly preferred way to do anything with SQL Server; use the SQL Native Client on Windows systems, and use the FreeTDS ODBC driver on *nix systems:
<?php
$stmt = $this->db->prepare("{?= CALL usp_myproc}");
$stmt->bindParam(1, $retval, PDO::PARAM_STR, 32);
$rs = $stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "The return value is $retval\n";
?>
The key thing here is that the return value can be bound as an OUT parameter, without having to restructure the stored procedures.
Just had this same problem:
<?php
function exec_sproc($sproc, $in_params)
{
global $database;
$stmnt = $database->prepare("EXEC " . $sproc);
if($stmnt->execute($in_params))
{
if($row = $stmnt->fetch())
{
return $row[0];
}
}
return -1;
}
?>
can't u use SELECT to return the results?
Then you can use a dataset (resultset in php?) to pick it up?
I don't know know PHP, but in c# its quite simple - use a dataset.
pretty sure PDO::exec only returns number of rows.. this would be $rs in your example
If I understand your question properly you shouldn't have to call fetchAll()...
$stmt = $this->db->prepare("EXECUTE usp_myproc ?, ?");
$stmt->bindParam(1, $mystr, PDO::PARAM_STR);
$stmt->bindParam(2, $mystr2, PDO::PARAM_STR);
$rs = $stmt->execute();
echo "The return values are: $mystr , and: $mystr2";
PDOStatement::bindParam
public function callProcedure($sp_name = null, $sp_args = []) {
try {
for($i = 0; $i < count($sp_args); $i++) {
$o[] = '?';
}
$args = implode(',', $o);
$sth = $connection->prepare("CALL $sp_name($args)");
for($i = 0, $z =1; $i < count($sp_args); $i++, $z++) {
$sth->bindParam($z, $sp_args[$i], \PDO::PARAM_STR|\PDO::PARAM_INPUT_OUTPUT, 2000);
}
if($sth->execute()) {
return $sp_args;
}
} catch (PDOException $e) {
this->error[] = $e->getMessage();
}
}
I had a similar problem and was able to solve it by returning the execute like so...
function my_function(){
$stmt = $this->db->prepare("EXECUTE usp_myproc ?, ?");
$stmt->bindParam(1, 'mystr', PDO::PARAM_STR);
$stmt->bindParam(2, 'mystr2', PDO::PARAM_STR);
return $stmt->execute();
}
All that is left is to call the function using a variable and then analyse said variable.
$result = my_function();
You can now analyse the contents of $result to find the information you're looking for. Please let me know if this helps!
Try $return_value