mysqli_affected_rows() always returns -1 - mysql

In my development environment, all calls to mysqli_affected_rows($link) are unexpectedly returning -1, indicating an error of some sort.
The identical SQL executed from a SQL console works as expected.
To avoid people trying to understand the code, I have written rewritten this question with a very simple test script, as follows:
<?php
// $DB parameters deleted
$link = #mysqli_connect($DBHOSTNAME, $DBUSER, $DBPASSWORD, $DBNAME);
$query = 'UPDATE control SET message = 66476 WHERE controlid = "lastgood"';
$rs = mysqli_query($link, $query);
$nbr = mysqli_affected_rows($link);
echo $nbr;
?>
This script returns -1. Something in my environment is clobbering mysqli_affected_rows().

There is a bug documented at https://bugs.php.net/bug.php?id=67348 with mysqli_affected_rows when operating through a debugger.

Related

Error while accessing MySQL resultset

When I executed this code,
while($row = mysql_fetch_array($res))
there was an error of the following plan:
Warning: mysql_fetch_array() expects parameter 1 to be resource,
boolean given in String of treatment:while($row =
mysql_fetch_array($res))
$res should be an resource , for example
$res = mysql_query("SELECT * FROM table;");
after that only use mysql_fetch_array. Just for information
This extension was deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be used.
Would be better to use mysqli_query instead of mysql_query. Read this answer and this PHP documentation about differences between them. So I advice you to use mysqli:
$result = mysqli_query($connection, 'SELECT id, name FROM some_table');
if($result){
while($row = mysqli_fetch_assoc($result)){
//extract values from row
$id = $row['id'];
$name = $row['name'];
}
}

Getting 2 Notice: Undefined Variable errors

The two errors are as below:
Notice: Undefined variable: HawA_Homes in C:\wamp\www\HawA_CIS241\InsertRecord.php on line 48
Notice: Undefined variable: HawA_Homes in C:\wamp\www\HawA_CIS241\InsertRecord.php on line 56
I've checked my names and they appear correct and I am not sure how to proceed now.
Code is as below:
<?php
$hostName = "localhost";
$databaseName = "test";
$userName = "root";
$password = "";
$tableName = "HawA_Homes";
//try to connect report error if cannot
$db = new mysqli($hostName, $userName, $password, $databaseName) or die(" Could not connect:" . mysql_error());
print(" Connection successful to host $hostName <br /> <br />"); //report connection success
//Get data to create a new record
$Address = $_REQUEST["address"];
$DateBuilt = $_REQUEST["dateBuilt"];
$Value = $_REQUEST["value"];
$Size = $_REQUEST["size"];
$Number_of_floors = $_REQUEST["floors"];
$sql = "INSERT INTO $HawA_Homes('Address','DateBuilt','Value','Size','Number_of_floors')VALUES{'$Address','$DateBuilt','$Value','$Size','$Number_of_floors')"; //Create insert query for new record
//try to query dataase / store returned results and report error if not successful
if(!$result =$db->query($sql))
{
//die('There was an error running the query[' .$db->error . ']';
}
print("SQL query $sql successful to database: $HawA_Homes <br /><br />"); //report sql query successful.
?>
You have these notices because the variable $HawA_Homes isn't declared in your code before being used at line 48 and 56. (These are just notices, they are not critical errors, you can avoid displaying them by adding error_reporting(E_ALL & ~E_NOTICE); at the begining of your code, like explained here)
In fact, you used $HawA_Homes instead of $tableName in these lines. Replace them, you won't have notices anymore for these lines.

MySQL 4.0 Gibberish Cannot Convert to Newer MySQL

One of the websites I host still runs on PHP 5.2 with MySQL 4.0. Its text is in Hebrew (displays just fine on the site), but in the DB the text appears as gibberish containing question marks—but not exclusively. It looks some like: ?????£ ?§???¥ ???£ ?×???
I am trying to move this DB to MySQL 5.x with the same website, with no luck so far. I have tried using the MYSQL 40 compatibility mode, as well as other compatibility modes. I have made sure that the destination DB has the hebrew_bin collation as the old one, and I've played around with SET NAMES. The problem is, this is a type of gibberish I am not yet familiar with and therefore have no idea how to convert it to readable text.
I didn't get another answer here, and therefore had no choice but to write a simple script that manually does the migration process through PHP and not through MySQL dumps.
Here is the script, with some obvious modifications. Please note that the script is "dirty code", it might not be secure and it's not the most efficient, but it should get the job done if you're using it internally. Do not use in an environment where the script is accessible to the public without further modifications.
<?php
$local = mysqli_connect([source server], [source username], [source password], [source DB name]) or die('No local connection');
mysqli_query($local, "SET NAMES 'hebrew'");
$remote = mysqli_connect([destination server], [destination username], [destination password], [destination DB name]) or die('No remote connection');
mysqli_query($remote, "SET NAMES 'utf8'");
$table_list = array('table1', 'table2', 'table3'); // you can get a list of tables automatically too if the list is very long
foreach ($table_list as $table)
{
$query_local = "SELECT * FROM `{$table}`";
$result_local = mysqli_query($local, $query_local) or die('Error in q1: '.mysqli_error($local));
$delete_remote = mysqli_query($remote, "DELETE FROM `{$table}` WHERE 1") or die('Error deleting table: '.$table); // necessary only if you plan to run it more than once
$i = 0;
while ($row_local = mysqli_fetch_assoc($result_local))
{
foreach ($row_local as $key => $value)
$row_local[$key] = mysqli_real_escape_string($remote, $value);
$query_remote = "INSERT INTO `{$table}` (`".implode('`, `', array_keys($row_local))."`) VALUES ('".implode("', '", $row_local)."')";
$result_remote = mysqli_query($remote, $query_remote)
or die('Error in remote q'.$i.' in table '.$table.':<br /> '.mysqli_error($remote).'<br /> Query: '.$query_remote);
echo 'Successfully transferred row '.$i.' in table '.$table;
echo '<br />'.PHP_EOL;
$i++;
}
}
?>

Fetching data from database in php file

I am trying to fetch data from table. Table contains the data and query is true. Even why following query says $u and $t are not define. While condition becoming false.
I manually checked in database, it was showing results.
$url = "http://paulgraham.com/";
$user_id = "123";
$con = mysqli_connect('127.0.0.1', 'root', '', 'mysql');
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
return;
}
$result = mysqli_query($con,"SELECT * FROM post_data WHERE userid =".$url." and url=".$user_id."");
while ($row = #mysqli_fetch_array($result))
{
echo "hi";
$t = $row['title'];
$u = $row['url'];
}
echo "title is : $t";
echo "url is : $u";
Giving your SQL query :
"SELECT * FROM post_data WHERE userid =".$url." and url=".$user_id.""
You can see you are mixing url and userid... Change to :
"SELECT * FROM post_data WHERE userid =".$user_id." and url=".$url.""
Also define your $t and $u variables before your loop in case you have no record.
Next time, try to var_dump your generated query to test it.
If you were able to see the errors the DBMS is reporting back to PHP then you'd probably be able to work out what's wrong with the code.
Before the 'while' loop try...
print mysql_error();
(the obvious reason it's failing is that strings mut be quoted in SQL, and you've got the parameters the wrong way around)

Update MySQL within Perl loop failing (fetchrow_array)

I've created a Perl script which is meant to loop through an array (a shortlist of customers who meet certain criteria), execute an external command using system() , then update a field within each row once the operation has completed.
It works on the first record (ie external command executes, customer record updates), however when it gets to the second record I receive this error:
DBD::mysql::st fetchrow_array failed: fetch() without execute() at customer_update.pl
Through some googling I added the $sth->finish(); command, however whether I include it or not (either inside the loop as shown, or straight afterward) I still get the same error.
Can anyone shed any light for me as to what I am doing wrong here?
Here's an extract:
# PERL MYSQL CONNECT()
$dbh = DBI->connect('dbi:mysql:signups', $user, $pw)
or die "Connection Error: $DBI::errstr\n";
# DEFINE A MySQL QUERY
$myquery = "SELECT * FROM accounts WHERE field3 = false";
$sth = $dbh->prepare($myquery);
# EXECUTE THE QUERY
$sth->execute
or die "SQL Error: $DBI::errstr\n";
#records = $sth->rows;
print "Amount of new customers: #records\n\n";
while ( my ($field1, $field2, $field3) = $sth->fetchrow_array() ) {
#execute external command via system();
$update_customer_status = "UPDATE accounts SET field3=true WHERE id=$id";
$sth = $dbh->prepare($update_customer_status);
$sth->execute
or die "SQL Error: $DBI::errstr\n";
print "Customer record modified & MySQL updated accordingly\n\n";
$sth->finish();
}
Building a SQL statement with variables and then prepare()ing it defeats the purpose of the prepare. You should build the SQL statement with a placeholder ? instead of $id, prepare() it, and then execute($id) it. As it is, you are leaving yourself open to SQL injection attacks.
Also, it seems that you are not using the warnings and strict pragmas. These two lines should be at the top of every program you write:
use warnings;
use strict;
They will save you much heartache and frustration in the future.
In your loop, you overwrite the handle over from which you are fetching. Use a different variable. (Changing $sth = ...; to my $sth = ...; will do.) While we're at it, let's move the prepare out of the loop.
my $sth_get = $dbh->prepare("SELECT * FROM accounts WHERE field3 = false");
my $sth_upd = $dbh->prepare("UPDATE accounts SET field3=true WHERE id = ?");
$sth_get->execute();
while ( my ($field1, $field2, $field3) = $sth_get->fetchrow_array() ) {
...
$sth_upd->execute($id);
}
You are stomping on your $sth variable when you execute this line ...
$sth = $dbh->prepare($update_customer_status);
Why not save off the result of $sth->fetchrow_array() to an array variable.
Something like ...
my #select_results_AoA = $sth->fetchrow_array();
... and then iterate over the array ...
for my #row ( #select_resilts_AoA ) {
... instead of ...
while ( my ($field1, $field2, $field3) = $sth->fetchrow_array() ) {