mysqli Fatal error: Call to a member function bind_param() on a non-object - mysqli

I have a problem with a prepared statement, here is my code:
function query_array($table, $data) {
foreach ($data as $column => $value) {
$columns[] = sprintf("`%s` = '%s'", $column, $this->db->real_escape_string($value));
}
$column_list = join(',', $columns);
// Prepare the statement
$stmt = $this->db->prepare("UPDATE `?` SET ?");
$stmt->bind_param('ss', $table, $column_list);
// Execute the statement
$stmt->execute();
// Save the affected rows
$affected = $stmt->affected_rows;
// Close the statement
$stmt->close();
// ...
}
$this->db returns an object;
$table = 'settings'; (string)
$column_list: (string)
`title` = 'Socialsd',`captcha` = '0',`public` = '',`private` = '',`time` = '1',`perpage` = '10',`message` = '140',`mail` = '1',`inter` = '10000',`size` = '1048576',`format` = 'png,jpg,gif',`sizeMsg` = '1048576',`formatMsg` = 'png,jpg,gif,bmp',`censor` = '',`ad1` = '',`ad2` = ''
The error I'm getting is:
Fatal error: Uncaught exception 'ErrorException' with message 'You
have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near '?' at line
1' in C:\xampp\htdocs\new\includes\classes.php:256 Stack trace: #0
C:\xampp\htdocs\new\sources\admin.php(225):
updateSettings->query_array('settings', Array) #1
C:\xampp\htdocs\new\index.php(42): PageMain() #2 {main} thrown in
C:\xampp\htdocs\new\includes\classes.php on line 256
I can't figure out what causes this, because trying the following works just fine:
$query = sprintf("UPDATE `%s` SET %s", $table, $column_list);
$result = $this->db->query($query);
Any help is appreciated.
Update 1: May I know why this has been down-voted? It would be nice to know.
Update 2: So I've removed the last bind ($column_list) and put in the statement the entire output of $column_list, so basically I was binding only the table name, and now I get another error:
Can't find file: '.\diary\#003f.frm' (errno: 22)
Now I'm really confused.

I have found the answer here: Use one bind_param() with variable number of input vars and also as #Jocelyn linked me, I've found that table names can't be binded. Can be closed.

Related

TYPO3, Extbase: mysqli error message, commands out of sync

I try to update a really old extbase extension which is from another programmer. TYPO3-Version is 8.7.13
The following function in my Repository throws the error:
"Commands out of sync; you can't run this command now
Doctrine\DBAL\Driver\Mysqli\MysqliException thrown in file
/Volumes/web/src/typo3_src-8.7.13/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php in line 249."
And this ist the function:
Public Function delete($standort, $month)
{
$m = date('m',$month);
$y = date('Y',$month);
$sql = "
DELETE FROM mytable
WHERE standort = ".$standort." AND FROM_UNIXTIME( monat, '%m' ) = $m AND FROM_UNIXTIME( monat, '%Y' ) = $y ";
$query = $this->createQuery();
$query->statement($sql);
$query->execute(TRUE);
}
with $query->execute(FALSE); no error is thrown but the sql is not executed. With $query->execute(TRUE); the error appears but the sql will be executed.
Can anybody help?
Thanks!
What about changing this statement to Doctrine? You can find the documentation here: https://docs.typo3.org/typo3cms/CoreApiReference/8.7/ApiOverview/Database/BasicCrud/Index.html#delete-a-row

Can't call method "execute" on an undefined value

Whenever I'm executing the program below, I get the error message Can't call method "execute" on an undefined value from following line:
$sth->execute($agent_name,$service_id,$call_start_time,$call_end_time);
but in same program I'm able to execute the first SQL query indicated in the comments below:
#!/usr/bin/perl -w
use strict;
use DBI;
my $DSN = q/dbi:ODBC:SQLSERVER/;
my $uid = q/ivr/;
my $pwd = q/ivr/;
my $DRIVER = "Freetds";
my $dbh = DBI->connect($DSN,$uid,$pwd) or die "Coudn't Connect SQL";
my $servernumber = 2;
my $service_name = "JM";
my $agent_name= 'Balaji';
my $call_start_time='2013-07-01 15:46:50.865';
my $call_end_time='2013-07-15 15:46:50.789';
my $call_rec_file_name;
my $rows_fund = $dbh->selectrow_array("select count(service_name) from cti_services where service_name='$service_name'");
my $rows_agent = $dbh->selectrow_array("select count(agent_name) from cti_agents where agent_name='$agent_name'");
# This query successfully executes:
my $sql_fund = "select service_id from cti_services where service_name='$service_name'";
my $sth_fund = $dbh->prepare($sql_fund);
$sth_fund->execute() or die $DBI::errstr;
my $service_id = $sth_fund->fetchrow();
print $service_id,"\n";
if( $rows_fund == 1 && $rows_agent == 1 )
{
my $sql="select top(10) service_name,agent_name,call_rec_file_name,call_start_time,call_end_time from cti_agents join cti_call_master on (agent_name = call_agent_name) join cti_services on (call_service_id = service_id) where agent_name = ? and call_rec_file_name is not null and service_id=? and call_start_time between ? and ?";
my $sth = $dbh->prepare($sql);
# The problem is with this query. I'm getting the error "Can't call method "execute" on an undefined value".
$sth->execute($agent_name,$service_id,$call_start_time,$call_end_time);
print "Service Name","Agent Name","Call Start Time ","Call End Time","Sound File " ;
while (my #data = $sth->fetchrow_array())
{
my ($service_name,$agent_name,$call_rec_file_name,$call_start_time,$call_end_time ) = #data;
print "$service_name","$agent_name ","$call_start_time ","$call_end_time "," $call_rec_file_name ";
}
}
else
{
print "<em>","There is no data found","</em>";
}
$dbh->disconnect;
What could be causing the error message?
$sth is undefined because your call to $dbh->prepare is failing for some reason.
If you replace your DBI->connect() call with the following, you'll get the error from the prepare call rather than it failing silently and bombing out when you try to call execute:
my $dbh = DBI->connect($DSN,$uid,$pwd, { RaiseError => 1 });
You can read more about RaiseError and the other attributes available to DBI calls here: https://metacpan.org/module/DBI#RaiseError
I must admit I can't immediately see the error, my hunch is an SQL syntax issue, but I don't speak SQLServer.
Change the first two lines inside the if to this
my $sth = $dbh->prepare(<<__SQL__) or die $dbh->errstr;
SELECT TOP(10) service_name, agent_name, call_rec_file_name, call_start_time, call_end_time
FROM cti_agents
JOIN cti_call_master ON (agent_name = call_agent_name)
JOIN cti_services ON (call_service_id = service_id)
WHERE agent_name = ?
AND call_rec_file_name IS NOT NULL
AND service_id = ?
AND call_start_time BETWEEN ? AND ?
__SQL__
then you will see the reason for the error.
Note that there must be no spaces before or after __SQL__.
Put quotes inside the sql for the datetimes, it may be seeing the white space during parsing?

Zend Framework - Issue with delete from database code

In my Application_Model_DbTable_User, I have the following function:
public function deleteUser($username)
{
$this->delete('username = ' . (string) $username);
}
This function is being called from my AdminController, with this three lines of code.
$uname = $this->getRequest()->getParam('username');
$user = new Application_Model_DbTable_User();
$user->deleteUser($uname);
This error however, turns up.
Column not found: 1054 Unknown column 'test' in 'where clause'
With test being the user I am trying to delete.
This code is adapted from a previous code which deletes based on id, a INT field, which works perfectly fine. What am I doing wrong? I would be happy to give more detailed codes if needed. Thanks.
Your query isn't quoted:
$this->delete('username = ' . (string) $username);
This equates to:
WHERE username = test
If you use the where() method, it will do this for you:
$table->where('username = ?', $username);
Or (like the example in the docs):
$where = $table->getAdapter()->quoteInto('bug_id = ?', 1235);
$table->delete($where);

Perl referencing and deferencing hash values when passing to subroutine?

I've been banging my head over this issue for about 5 hours now, I'm really frustrated and need some assistance.
I'm writing a Perl script that pulls jobs out of a MySQL table and then preforms various database admin tasks. The current task is "creating databases". The script successfully creates the database(s), but when I got to generating the config file for PHP developers it blows up.
I believe it is an issue with referencing and dereferencing variables, but I'm not quite sure what exactly is happening. I think after this function call, something happens to
$$result{'databaseName'}. This is how I get result: $result = $select->fetchrow_hashref()
Here is my function call, and the function implementation:
Function call (line 127):
generateConfig($$result{'databaseName'}, $newPassword, "php");
Function implementation:
sub generateConfig {
my($inName) = $_[0];
my($inPass) = $_[1];
my($inExt) = $_[2];
my($goodData) = 1;
my($select) = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = '$inName'");
my($path) = $documentRoot.$inName."_config.".$inExt;
$select->execute();
if ($select->rows < 1 ) {
$goodData = 0;
}
while ( $result = $select->fetchrow_hashref() )
{
my($insert) = $dbh->do("INSERT INTO $configTableName(databaseId, username, password, path)".
"VALUES('$$result{'id'}', '$inName', '$inPass', '$path')");
}
return 1;
}
Errors:
Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 142.
Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 154.
Line 142:
$update = $dbh->do("UPDATE ${tablename}
SET ${jobStatus}='${newStatus}'
WHERE id = '$$result{'id'}'");
Line 154:
print "Successfully created $$result{'databaseName'}\n";
The reason I think the problem comes from the function call is because if I comment out the function call, everything works great!
If anyone could help me understand what's going on, that would be great.
Thanks,
p.s. If you notice a security issue with the whole storing passwords as plain text in a database, that's going to be addressed after this is working correctly. =P
Dylan
You do not want to store a reference to the $result returned from fetchrow_hashref, as each subsequent call will overwrite that reference.
That's ok, you're not using the reference when you are calling generate_config, as you are passing data in by value.
Are you using the same $result variable in generate_config and in the calling function? You should be using your own 'my $result' in generate_config.
while ( my $result = $select->fetchrow_hashref() )
# ^^ #add my
That's all that can be said with the current snippets of code you've included.
Some cleanup:
When calling generate_config you are passing by value, not by reference. This is fine.
you are getting an undef warning, this means you are running with 'use strict;'. Good!
create lexical $result within the function, via my.
While $$hashr{key} is valid code, $hashr->{key} is preferred.
you're using dbh->prepare, might as well use placeholders.
sub generateConfig {
my($inName, inPass, $inExt) = #_;
my $goodData = 1;
my $select = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = ?");
my $insert = $dbh->prepare("
INSERT INTO $configTableName(
databaseID
,username
,password
,path)
VALUES( ?, ?, ?, ?)" );
my $path = $documentRoot . $inName . "_config." . $inExt;
$select->execute( $inName );
if ($select->rows < 1 ) {
$goodData = 0;
}
while ( my $result = $select->fetchrow_hashref() )
{
insert->execute( $result->{id}, $inName, $inPass, $path );
}
return 1;
}
EDIT: after reading your comment
I think that both errors have to do with your using $$result. If $result is the return value of fetchrow_hashref, like in:
$result = $select->fetchrow_hashref()
then the correct way to refer to its values should be:
print "Successfully created " . $result{'databaseName'} . "\n";
and:
$update = $dbh->do("UPDATE ${tablename}
SET ${jobStatus}='${newStatus}'
WHERE id = '$result{'id'}'");
OLD ANSWER:
In function generateConfig, you can pass a reference in using this syntax:
generateConfig(\$result{'databaseName'},$newPassword, "php");
($$ is used to dereference a reference to a string; \ gives you a reference to the object it is applied to).
Then, in the print statement itself, I would try:
print "Successfully created $result->{'databaseName'}->{columnName}\n";
indeed, fetchrow_hashref returns a hash (not a string).
This should fix one problem.
Furthermore, you are using the variable named $dbh but you don't show where it is set. Is it a global variable so that you can use it in generateConfig? Has it been initialized when generateConfig is executed?
This was driving me crazy when I was running hetchrow_hashref from Oracle result set.
Turened out the column names are always returned in upper case.
So once I started referencing the colum in upper case, problem went away:
insert->execute( $result->{ID}, $inName, $inPass, $path );

Zend fetchRow() not working

I'm trying to fetch a row with a where statement but for some reason it throws an error at me.
This is the line
$row = $this->getDbTable()->fetchRow("order = $order");
I've put a die(); before this line and it does die,
Then I've put a die(); after this line and the die() doesn't get executed but throws an error.
The error doesn't help me much it only says "An error occurred Application error", there's nothing in my php error log either.
Help!
Going by your comments, I would try doing the where part 'properly'? E.g.:
$select = $this->getDbTable()->select()->where('order = ?', $order);
$row = $this->getDbTable()->fetchRow($select);
What is the situation you are needing to select by order? Is there a primary key you can select by?
Update:
Given your comments, maybe use update directly:
$table = $this->getDbTable();
$data = array( 'order' => $order+1 );
$where = $table->getAdapter()->quoteInto('order = ?', $order);
$table->update($data, $where);