I'm having an issue with sqlsrv_query();
I dont think this is a duplicate as i have been searching through other questions, but if it is i do apologise.
I have two php files one with the databse functions and one using them, the database file is included in the top of the file using it.
In the databse file i have two functions (Along with other connection functions);
function database_GetData($sql) {
$connection = database_GetDatabaseConnection();
return sqlsrv_query($connection, $sql);
}
function database_ReadData($rs) {
if (!$rs)
return false;
$data = sqlsrv_fetch_array($rs);
return $data;
}
The issue is that the database_GetData($sql) returns the resource but it is "unknown". If i print the sqlsrv_query($connection, $sql) result in the function or do something along the lines of sqlsrv_fetch_array(sqlsrv_query($connection, $sql)) within the function i get the expected result but as soon as i return the resource it gets messed up. The connection is all fine as i get the expected result but cannot return it. I would like to keep the functions the same as they are used throughout the application.
Is there any reason why a result of sqlsrv_query($connection, $sql) would get set to 'unknown' once returned from database_GetData($sql) function?
by ref parameters
function database_GetData($sql,&$resutl) {
$connection = database_GetDatabaseConnection();
$result=sqlsrv_query($connection, $sql);
return $result;
}
Related
I am having a strange issue with mysqli_num_rows. Searching for this issue, I've only found people having issues where NULL is returned no matter what. I also checked the official documentation for the function, and it says it returns an integer of the number of rows returned by the query. Whenever my query returns 1 row (it never should return more), it behaves as I expect. When the query returns 0 rows, I expect the function to return 0, but it returns NULL. Why doesn't it return 0?
I know that my database connection is good and my query works correctly, because when I look for a record that's in the database, I get an integer back. I just can't figure out why this is returning NULL rather than 0.
function getArtistID($name) {
global $conn;
$query = "SELECT artist_id FROM artist WHERE artist_name LIKE '${name}'";
$result = mysqli_query($conn, $query);
if ($result->num_rows) {
$row = mysqli_fetch_assoc($result);
return $row['artist_id'];
} else {
return 0;
}
}
Here's some code that I used to reproduce a case where num_rows seems to be NULL:
<?php
error_reporting(E_ALL);
$conn = new mysqli('127.0.0.1', 'root', null, 'test');
$sql = "SELECT * FROM dual";
$result = $conn->query($sql);
if ($result === false) {
print "Error: {$conn->error}\n";
}
$n = $result->num_rows;
echo "Dump the num_rows property: ";
var_dump($n);
Output:
Error: No tables used
Notice: Trying to get property of non-object in /Users/bkarwin/Documents/SO/my.php on line 14
Dump the num_rows property: NULL
The notice is because it's invalid to access an object-oriented property of a variable that is not an object. This is a frequent source of confusion for PHP developers, and it's a byproduct of the fact that PHP is a loosely typed language, and functions like query() can return either a result object, or a boolean scalar.
The query() function actually returned a false as $result because of some error. In my code, I checked for this error, and you didn't.
When you run mysqli::query() or mysqli::prepare() or mysqli_stmt::execute(), you must check for error conditions every time.
Something about your query caused an error. It's up to you to check for the error and report it.
Update: I edited some text above to make the explanation better, but it might make some comments below seem out of place.
I just can't figure out why this is returning NULL rather than 0.
We can only guess without seeing the log output; but, it is likely the return value is null because it raised an error instead.
You need to ensure that errors are handled when calling a function, before attempting to use the return value.
My PHP code:
function get_something() {
global $link;
$sql = "SELECT * FROM new";
$result = mysqli_query($link, $sql);
$names = mysqli_fetch_all($result, MYSQLI_ASSOC);
return $names;
}
What is my problem:
When my table new is empty, I get the following error:
mysqli_fetch_all() expects parameter 1 to be mysqli_result`
If it isn't empty everything is working fine.
I need to check if my database is empty and if it's not, I will call mysqli_fetch_all. Otherwise, my function should return an empty array.
How is this possible to do?
Use mysqli_num_rows($result) to check how many rows were returned from the query. But if table new doesn't exist, $result will be false so we have to check that $result is valid as well:
if ($result && mysqli_num_rows($result) > 0)
$names = mysqli_fetch_all($result, MYSQLI_ASSOC);
else
$names = array();
return $names;
mysqli_fetch_all($result, MYSQLI_ASSOC) generates an indexed array of associative arrays. When there are no rows found, it will deliver an empty array (which is what you want). It is absolutely pointless to call mysqli_num_rows(), so don't make your script do any unnecessary work.
Furthermore:
many developers will advise you not to make global declarations to pass variables in your custom function scope. Instead, pass the connection variable into your function as a parameter.
I always try to avoid declaring single use variables. For your case, $sql and $names will only be used/referenced once after being declared, so just don't declare them.
As a matter of personal preference, I recommend using OO syntax with mysqli functions because it is less verbose, but in my following snippet I'll leave it like your original post.
Suggested Code:
function get_something($link) {
if (!$result = mysqli_query($link, "SELECT * FROM new")) {
return []; // check mysqli_error($link) because your query failed
}
return mysqli_fetch_all($result, MYSQLI_ASSOC);
}
I'm trying to fill 2 dropdowns from database, so I try to make one query and fill the first dropdown and then trying to make the second and fill the last dropdown.
It returns the second $rows as false but first is ok, what am I doing wrong?
<?php
$db = new Db();
$rows = $db -> select("call Store1(0,0);");
var_dump($rows);
$rows = $db -> select("call Store1(0,0);");
var_dump($rows);
?>
These are my 2 functions:
public function select($query) {
$rows = array();
$result = $this -> query($query);
if($result === false)
{
return false;
}
while ($row = $result -> fetch_assoc())
{
$rows[] = $row;
}
return $rows;
}
public function query($query) {
$connection = $this -> connect();
$result = $connection -> query($query);
return $result;
}
My guess (and this is just a guess...)
The first resultset (cursor) is still open. The cursor hasn't been closed. (Myabe there are more rows remaining in the current resultset which haven't been fetched yet. Or haven't been discarded by issuing a close.
And an attempt to prepare (execute) a second statement (on that same database connection) is causing an error.
(Agian, this is just a guess, by no means an actual diagnosis of the problem.)
My recommendation would be that we enable error reporting. If a SQL statement execution is returning FALSE, then we need to retrieve the error code and error message from the database. Or consider enabling PDO exceptions, so that errors are thrown so we can see them. (Something similar is probably available using mysqli.)
The return of FALSE is telling us that an error occurred, but it doesn't tell us what the error is. (And without that, it's going to be very difficult to know what to fix.)
In some cases, it may be that we don't care what the error is. In this case, it's pretty clear that we do care. And it's our job to find out what the error is... without diagnosing the root cause of the error, any attempt at writing a prescription is going to be a "try this" and "try that" shooting in the dark without aiming, hoping to hit something.
Recommended reading:
https://ericlippert.com/2014/03/05/how-to-debug-small-programs/
I'm trying my hand at custom functions in PHP in order to streamline a lot of stuff I'm otherwise doing manually. I'm damn new to custom functions so I'm not sure the limitations. Right now I'm trying to get data with MySQLi using custom functions Here's the code, and then I'll explain the issue:
function connect_db($db = 'db_username') {
iconv_set_encoding("internal_encoding", "UTF-8");
mb_language('uni');
mb_internal_encoding('UTF-8');
# $mysqli = new mysqli('host',$db,'password',$db);
if(mysqli_connect_errno())
{
die('connection error');
}
}
This one seems to be working fine. It's the next function I'm having more trouble with.
edit: Updated thanks to Jeremy1026's response
function do_query($db = 'default_db', $query) {
connect_db();
$result = $mysqli->query($query);
if(!$result){
trigger_error("data selection error");
}
while($row = $result->fetch_assoc()){
$result_array[] = $row;
}
return $result_array;
}
My host forces database names and usernames as the same, so if the db name is 'bob' the username to access it will be 'bob' as well, so that's why $db shows up twice in the connection.
The problem I'm having is that these two functions are in functions.php and being called from another page. I want to be able to pull the results from the query in that other page based on the column name. But I also need to be able to do this with formatting, so then maybe the while() loop has to happen on that page and not in a function? I want this to be as universal as possible, regardless of the page or the data, so that I can use these two functions for all connections and all queries of the three databases I'm running for the site.
God I hope I'm being clear.
Big thanks in advance for any suggestions. I've googled this a bit but it's tough to find anything that's not using obsolescent mysql_ prefixes or anything that's actually returning the data in a way that I can use.
Update: I'm now getting the following error when accessing the page in question:
Fatal error: Call to a member function query() on a non-object in /functions.php`
with the line in question being $result = $mysqli->query($query);. I assume that's because it thinks $query is undefined, but shouldn't it be getting the definition from being called in the page? This is that page's code:
$query = "SELECT * FROM `table`";
$myArray = do_query($db, $query);
echo $myArray['column_name'];
In your 2nd function you aren't returning any data, so it is getting lost. You need to tell it what to return, see below:
function do_query($db = 'default_db', $query) {
connect_db();
$result = $mysqli->query($query);
if(!$result){
trigger_error("data selection error");
}
while($row = $result->fetch_assoc()){
$result_array[] = $row;
}
return $result_array;
}
Then, when using the function you'll do something like:
$myArray = do_query($db, 'select column from table');
$myArray would then be populated with the results of your query.
This is a half-answer. The following single function works in place of the two.
function query_db($database, $new_query) {
$sqli = new mysqli('host', $database, 'password', $database);
$sqli->set_charset("utf8");
global $result;
if($result = $sqli->query($new_query)){
return $result;
}
}
By adding global $result I was able to access the results from the query, run from another page as
query_db("username","SELECT * FROM `column`");
while($row = $result->fetch_assoc()){
print_r($row);
}
It's more streamlined than I have without functions, but it's still not idea. If I have the connection to the database in another function, it doesn't work. If I try to put the while loop in the combined function, it doesn't work. Better than nothing, I guess.
I am new to php but not as a programmer...
I am having difficulty calling and displaying the content when I call a procedure more than once in a page. I am trying to display two separate record sets from two different SP calls for MYSQL. I can display the first call but the second fails. I'm not sure what I am doing wrong but perhaps someone can kind help?
I keep getting the error when I call the second procedure:
Error calling SPCommands out of sync; you can't run this command now
I'm running on windows btw
Code below... PHP
// First call to SP
$page = 2;
$section = 1;
include("DatabaseConnection.php"); //general connection - works fine
$sql = 'CALL GetPageContent("'.$page.'", "'.$section.'")';
$result = mysqli_query($conn, $sql) or die('Error calling SP' .mysqli_error($conn));
while($row=mysqli_fetch_assoc($result))
{
// DO STUFF< REMOVED TO MAKE READING CLEARER
}
mysqli_free_result($result);
//SECOND CALL BELOW
$section = 2; // change parameter for different results
$sql = 'CALL GetPageContent("'.$page.'", "'.$section.'")';
$result = mysqli_query($conn, $sql) or die('Error calling SP' .mysqli_error($conn));
while($row=mysql_fetch_assoc($result))
{
// DO STUFF< REMOVED TO MAKE READING CLEARER
}
mysqli_free_result($result);
The trouble is that your SP is giving you multiple results.
Use the mysqli_multi_query, see http://us2.php.net/mysqli_multi_query