My project runs fine on local machine, but not on web server - php

My project is working fine on my local machine but not on the web server. I think it is the stored procedures, because the error that I am getting is:
Fatal error: Call to a member function fetch_array() on a non-object in ...
The collation of the database is "utf8_general_ci".
Just a simple example:
I have a stored procedure called offices:
CREATE PROCEDURE offices()
BEGIN
SELECT * FROM offices;
END//
And the php code:
<?php
require ("db.php");
$db = dbConnect();
$result = $db->query("CALL offices()");
while(list($id, $city, $address) = $result->fetch_array())
echo "($id) $city: $address ";
?>

What happens on the database server, when you CALL offices() manually? Any errors? If I had to guess, it looks like the offices() function is not defined on the server, or fails when invoked (table offices doesn't exist?).

To me it looks like the $result is not a object or not initialized. Can you show us the code in your db library. Specifically the query function...

Make sure your db user which was used to install the schema has privileges to create stored procedures. If you are unsure if they are on the server, you can do
SELECT * FROM `information_schema`.`ROUTINES`;
..to see which procedures have been succesfully created.
Keep in mind the majority of shared hosting services do not support triggers, procedures etc.

you are probably running a different version of your database at the remote server.
so the query method is failing and is not returning what should return.

Looks like your auth does not have allowed to use DB procedures at the server

Related

Laravel and stored procedures SQL

I have a stored procedure that client has made.
Now I have to access it and process data in my laravel app.
I have no problems with connecting to SQL but the problems starts when passing in parameters.
Here is my code:
$connections = DB::connection('sqlsrv')
->select(EXEC [stored].[procedure].[here] $param1, $param2);
The error I got back is:
The active result for the query contains no fields
I have searched for many hours in forums and here is what I have found:
$connections = DB::connection('sqlsrv')
->select(DB::raw('EXEC [stored].[procedure].[here] $param1, $param2'));
Error I got back is:
The active result for the query contains no fields.
I have installed SQL driver and OBDC driver.
Any help would be much appreciated
Don't know if this will help but this answer suggests you put your DB::raw around just the params instead of the EXEC stored.proc.name.
So instead of
$connections = DB::connection('sqlsrv')->select(DB::raw('EXEC [stored].[procedure].[here] $param1, $param2'));
Try
$connections = DB::connection('sqlsrv')->select('EXEC stored.proc.name' . DB::raw($param1, $param2));
OK. So I found out the issue.
It turns out the client sent me over a variable with xml.
As far as I figured out from Microsoft docs then you cant pass xml as a varable because if you call the SP from an application it is gonna pass it as an array and application cant parse xml into array directly. You have to do it on your own.
What can be done instead is to pass xml as a value of an array and then take it from there.

Internal Server Error with linking database in PHP

I have a database that I want to use to make an array for an app I'm working on in Xcode. I'm following a tutorial I found on the internet here, and I followed the instructions, but my page is displaying an Internal Server Error. I am assuming that I didn't correctly change the info in the following code. Also, my web host uses MYSQL not MYSQLite, so I'm not sure what to change the "new mysqli" to in the code. For obvious reasons I omitted the database info. The database has one table named "descriptions" and the columns are labeled 1-50 with different values assigned.
<?php
class RedeemAPI {
private $db;
// Constructor - open DB connection
function __construct() {
$this->db = new mysqli('hostname', 'Username', 'Pass', 'Database Name');
$this->db->autocommit(FALSE);
}
// Destructor - close DB connection
function __destruct() {
$this->db->close();
}
// Main method to redeem a code
function redeem() {
// Print all codes in database
$stmt = $this->db->prepare('SELECT 1 FROM descriptions');
$stmt->execute();
$stmt->bind_result($1);
while ($stmt->fetch()) {
echo "$1";
}
$stmt->close();
}
}
// This is the first thing that gets called when this page is loaded
// Creates a new instance of the RedeemAPI class and calls the redeem method
$api = new RedeemAPI;
$api->redeem();
?>
PHP variables must start with a letter or _, so your error stems from this statement:
$stmt->bind_result($1);
Change the variable name to something like $col1, or whatever is meaningful.
Also, your select statement will return a single value: 1. You probably mean to do this:
SELECT * FROM descriptions
Two other points:
You shouldn't disable autocommit unless you intend to use transactions.
There's no need to prepare statements with simple queries that don't include untrusted input. You can just use $this->db->query("...")'. You'd need to tweak the other statements to match if you change this.
That internal server error 500 is probably masking some lovely error messages that may help. Switch your debugging on in your php.ini / php5.ini
Add this to your php.ini / php5.ini or just add one of these files to the root of your website should do the trick
display_errors = On
display_startup_errors = On
error_reporting = -1
Second, if your host is not running MYSQLi, then they are running REALLY old php as MYSQLi is standard in php4.1.3 and above
Third, that SQL statement.. its it just some kind of rough example or is that your actual statement? If you are trying to pull off one record it should be
SELECT * FROM tablename.description LIMIT 1
Always best to make your statements very thorough

PHP's SQLSRV driver would not complete a Stored Procedure query that works normally elsewhere

So I'm confident that the stored procedure works, I've tested it in SQL Server Management Studio just fine and it runs in other service instances. The query used to run this SP follows;
exec sp_getAgentCommissionDetails_v3 201000023762230, 5
So it runs fine on SSMS and under the old MSSQL driver. But I run the query with SQLSRV like so;
function mssql_query($string, $linkID = null, $batch = 0) {
if (!$linkID) {
global $dbhandle;
$linkID = $dbhandle;
}
// SQLSRV_CURSOR_KEYSET ensures mssql_num_rows() works in most cases. Default scrollablility does not support this.
return sqlsrv_query($linkID, $string, array(), array("Scrollable" => SQLSRV_CURSOR_KEYSET));
}
The function is named mssql_query because we're updating an old system from MSSQL to SQLSRV, but we're working with an extremely messy old system. So rather than trying to refactor it we're overwriting the MSSQL_query function (having disabled the mssql extension) with one that uses SQLSRV.
$dbhandle is our SQLSRV connection resource. Other queries run just fine using this method.
So my question- is there any reason the query to run a stored procedure would not run under this SQLSRV function?
Couple notes on my troubleshooting;
I'm aware SQLSRV and PDO have a specific method to run stored procedures. Using that is not an option due to the massive codebase that uses the method above in various places and because we haven't got the man hours to refactor every page.
I pulled up SQLSRV_errors() and it returned 'Executing SQL directly; no cursor'. After a bit of research this seems to be a bug in the driver that returns this generic error message instead of a more specific useful one, so it can mean very many things.
There are no cursors or loops involved in the stored procedure.
Found a solution to this. SQLSRV seems to by default treat warnings as errors. Fixed this with a config change in the connection file;
sqlsrv_configure("WarningsReturnAsErrors",0);
It now runs fine.

How to use PHPUnit administrative connection to query DB?

Using the PHPUnit administrative connection to the database would avoid "polluting" any logging or other things going on inside of our app code with an SQL command that's only being used to implement the test.
I'd like to use $this->getConnection() to grab the administrative PHPUnit connection to the database rather than call our SystemDB::query() function directly, but I can't seem to get the syntax correct. Any thoughts would be appreciated.
This worked:
$result = $this->getConnection()->getConnection();
$query = $result->query( $sql );
$my_array = $query->fetchAll();
where $sql is the query and getConnection() is implemented according to the main phpUnit manual page http://phpunit.de/manual/current/en/database.html

Call Multiple Stored Procedures with the Zend Framework

I'm using Zend Framework 1.7.2, MySQL and the MySQLi PDO adapter. I would like to call multiple stored procedures during a given action. I've found that on Windows there is a problem calling multiple stored procedures. If you try it you get the following error message:
SQLSTATE[HY000]: General error: 2014
Cannot execute queries while other
unbuffered queries are active.
Consider using
PDOStatement::fetchAll().
Alternatively, if your code is only
ever going to run against mysql, you
may enable query buffering by setting
the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
attribute.
I found that to work around this issue I could just close the connection to the database after each call to a stored procedure:
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
//If on windows close the connection
$db->closeConnection();
}
This has worked well for me, however, now I want to call multiple stored procedures wrapped in a transaction. Of course, closing the connection isn't an option in this situation, since it causes a rollback of the open transaction. Any ideas, how to fix this problem and/or work around the issue.
More info about the work around
Bug report about the problem
I has same errors when called queries like this(variables to use in next query)
$db->query("SET #curr = 0.0;");
To fix this I've changed my config file to
'database' => array(
'adapter' => 'mysqli',
This pattern of preparing, executing and then closing each $sql statement that calls a stored procedure does work.
public function processTeams($leagueid,$raceid,$gender)
{
$db = Zend_Db_Table::getDefaultAdapter();
$sql = $db->prepare(sprintf("CALL addScoringTeams(%d,%d,'%s')",$leagueid,$raceid,$gender));
$sql->execute();
$sql->closeCursor();
$this->logger->info(sprintf("CALL addScoringTeams(%d,%d,'%s')",$leagueid,$raceid,$gender));
$sql1 = $db->prepare(sprintf("CALL updateScoringTeamTotals(%d)",$raceid));
$sql1->execute();
$sql1->closeCursor();
$this->logger->info(sprintf("CALL updateScoringTeamTotals(%d)",$raceid));
$sql2 = $db->prepare(sprintf("CALL updateScoringTeamClasses(%d,'%s')",$raceid,$gender));
$sql2->execute();
$sql2->closeCursor();
$this->logger->info(sprintf("CALL updateScoringTeamClasses(%d,'%s')",$raceid,$gender));
}
You can use prepare statement . No need to change driver
$sql = "CALL procedure()";
$stmt = $this->db->createStatement();
$stmt->prepare($sql);
$result = $stmt->execute();

Categories