I am trying to execute a prepared statement with mysqli but the statement never executes with results nor throws an error. But executing the query normally work.
The prepared query looks like this:
SELECT * FROM games WHERE YEARweek(game_date)=?
The regular non prepared query is this
SELECT * FROM games WHERE YEARweek(game_date)= YEARweek(current_DATE) +1
Any ideas why?
The code for executing the query is in different places but it looks like this in short version:
$WHERE_CLAUSE='';
$first=true;
if(isset($conditions['conditions'])) {
foreach($conditions['conditions'] as $key=>$condition){
if(is_array($condition)){
} else {
if($first)
$WHERE_CLAUSE.=$key.'=?';
else
$WHERE_CLAUSE.=' AND '.$key.'=?';
$input_data[$key]=$condition;
$first=false;
}
}//end foreach
if(!empty($WHERE_CLAUSE)){
$query.='WHERE '.$WHERE_CLAUSE.' ';
}
}
$result=PVDatabase::preparedSelect($query, $input_data);
public static function preparedQuery($query, $data, $formats = '') {
if (self::_hasAdapter(get_class(), __FUNCTION__))
return self::_callAdapter(get_class(), __FUNCTION__, $query, $data, $formats);
if (self::$dbtype == self::$mySQLConnection) {
self::$link -> prepare($query);
$count = 1;
foreach ($data as $key => $value) {
self::$link -> bindParam($count, $value);
$count++;
}//end foreach
return self::$link -> execute();
} else if (self::$dbtype == self::$postgreSQLConnection) {
$result = pg_prepare(self::$link, '', $query);
$result = pg_execute(self::$link, '', $data);
return $result;
} else if (self::$dbtype == self::$oracleConnection) {
} else if (self::$dbtype == self::$msSQLConnection) {
$stmt = sqlsrv_prepare(self::$link, $query, $data);
return sqlsrv_execute($stmt);
}
}//end preparedQuery
Since you haven't provided the code you're using to invoke the query, I'm going to guess that you are probably binding a value that includes an expression. Instead of being evaluated, it'll be interpreted literally.
PDO must be escaping the YEARweek(current_DATE) +1 part of the second query.
Do this instead:
$next_year = date('Y) + 1;
SELECT * FROM games WHERE YEARweek(game_date) = $next_year
Related
this is my code I want to convert this query in to a common query
if ($limit == 0) {
$response = WebhookErrorNotification::where('is_error', true)->orderByDesc('id')->get();
} else {
$response = WebhookErrorNotification::where('is_error', true)->orderByDesc('id')->limit($limit)->get();
}
You can save the query in a variable above the if/else statement. So something like this would work. Now if this is not the answer you are looking for please specify what you mean by common query!
$query = WebhookErrorNotification::where('is_error', true)->orderByDesc('id');
if ($limit == 0) {
$response = $query->get();
} else {
$response = $query->limit($limit)->get();
}
you can do something like this
$response = WebhookErrorNotification::where('is_error', true)
->when($limit !== 0, function ($query) use ($limit) {
$query->limit($limit);
})->orderByDesc('id')->get();
I have some php file which needs to use SQL. In that SQL I get multiple results and I use here a while($stmt->fetch()){} loop inside which I need to use another SQL. Can this be accomplished or do I need to store result of the first SQL query and after closing it I can open new SQL query.
Here's code:
function compute_production($local_id, $GameID) {
global $mysqli, $M, $Q;
$sql = "SELECT `x`, `y`, `building`, `tier` FROM `GOD_battlefields` WHERE `owner`=? AND `game_id`=?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ii", $local_id, $GameID);
$stmt->execute();
$stmt->bind_result($x, $y, $BUILDING, $TIER);
while($stmt->fetch()) {
$AB_triggered = array();
fOReaCh(tech_get_value($BUILDING, "abilities") as $ability_name => $required_tier) {
if ($TIER >= $required_tier) {
switch($ability_name) {
case "auto_production":
$AB_triggered[$ability_name] = "true";
break;
case "toggle_production":
case "double_production":
// check if the order is clicked
$sql = "SELECT `post_value` FROM `GOD_cache` WHERE `post_name`=? AND `post_value` LIKE ? AND `game_id`=? AND `round`=?";
$AB_triggered[$ability_name] = "false";
$post_name = 'AbilityOrder_'.$x.'_'.$y;
$stmt2 = $mysqli->prepare($sql);
$stmt2->bind_param("ssii", $post_name, $ability_name, $GameID, $Q->game_round);
$stmt2->execute();
$stmt2->bind_result($AbilityOrder);
if ($stmt2->fetch()) {
$stmt2->close();
$AB_triggered[$ability_name] = "true";
} else {
// Keep calm and do nothing
// Everything is fine
// No action needed
// Really
}
break;
}
}
}
foreach(tech_get_value($BUILDING, "production") as $r => $value) {
if ($r == "s" || $r == "io" || $r == "w") {
// check if cell contains those resources
$multiplier = ($Q->resources_in_cell($x, $y)[$r] > $value ? 1 : 0.15);
$value *= $multiplier; // Multiply gained resources --> if mines/forests/quarries are empty, gained resources are decreased
}
$value *= tech_get_value($BUILDING, "productionm", $r) ** ($TIER - 1);
if ($AB_triggered["toggle_production"] == "true" || $AB_triggered["auto_production"] == "true") {
$RES_PER_TURN[$r] += $value;
}
}
// information about production costs
$HTML_battlefield .= "for the cost of: <br />";
foreach(resources_for_production_gen($x, $y, array($BUILDING, $TIER)) as $resource => $cost) {
if ($AB_triggered["toggle_production"] == "true" || $AB_triggered["auto_production"] == "true") {
$RES_PER_TURN[array_search($resource, $dictionary_resource)] -= $cost;
}
}
}
return $RES_PER_TURN;
}
Keeps throwing errors on the $stmt2->bind_param();
The answer is: there is no way, how to maintain multiple open queries.
Solution may be using some INNER JOIN, or other JOIN or storing the information from first SQL, close the SQL and then open the next SQL and use stored information.
Before I begin, I want to point out that I can solve my problem. I've rehearsed enough in PHP to be able to get a workaround to what I'm trying to do. However I want to make it modular; without going too much into detail to further confuse my problem, I will simplify what I am trying to do so that way it does not detract from the purpose of what I'm doing. Keep that in mind.
I am developing a simple CMS to manage a user database and edit their information. It features pagination (which works), and a button to the left that you click to open up a form to edit their information and submit it to the database (which also works).
What does not work is displaying each row from MySQL in a table using a very basic script which I won't get into too much detail on how it works. But it basically does a database query with this:
SELECT * FROM users OFFSET (insert offset here) LIMIT (insert limit here)
Essentially, with pagination, it tells what number to offset, and the limit is how many users to display per page. These are set, defined, and tested to be accurate and they do work. However, I am not too familiar how to handle these results.
Here is an example query on page 2 for this CMS:
SELECT * FROM users OFFSET 10 LIMIT 10
This should return 10 rows, 10 users down in the database. And it does, when I try this command in command prompt, it gives me what I need:
But when I try to handle this data in PHP like this:
<?php
while ($row = $db->query($pagination->get_content(), "row")) {
print_r($row);
}
?>
$db->query method is:
public function query($sql, $type = "assoc") {
$this->last_query = $sql;
$result = mysql_query($sql, $this->connection);
$this->confirm_query($result);
if ($type == "row") {
return mysql_fetch_row($result);
} elseif ($type == "assoc" || true) {
return mysql_fetch_assoc($result);
} elseif ($type == "array") {
return mysql_fetch_array($result);
} elseif ($type == false) {
return $result;
}
}
$pagination->get_content method is:
public function get_content() {
global $db;
$query = $this->base_sql;
if (!isset($_GET["page"])) {
$query .= " LIMIT {$this->default_limit}";
return $query;
} elseif (isset($_GET["page"]) && $_GET["page"] == 1) {
$query .= " LIMIT {$this->default_limit}";
return $query;
} elseif (isset($_GET["page"])) {
$query .= " LIMIT {$this->default_limit}";
$query .= " OFFSET " . (($_GET["page"] * $this->default_limit) - 10);
return $query;
}
}
And my results from the while loop (which should print out each row of the database, no?) gives me the same row everytime, continuously until PHP hits the memory limit/timeout limit.
Forgive me if its something simple. I rarely ever handle database data in this manner. What I want it to do is show the 10 users I requested. Feel free to ask any questions.
AFTER SOME COMMENTS, I'VE DECIDED TO SWITCH TO MYSQLI FUNCTIONS AND IT WORKS
// performs a query, does a number of actions dependant on $type
public function query($sql, $type = false) {
$sql = $this->escape($sql);
if ($result = $this->db->query($sql)) {
if ($type == false) {
return $result;
} elseif ($type == true || "assoc") {
if ($result->num_rows >= 2) {
$array;
$i = 1;
while ($row = $result->fetch_assoc()) {
$array[$i] = $row;
$i++;
}
return $array;
} elseif ($result->num_rows == 1) {
return $result->fetch_assoc();
}
} elseif ($type == "array") {
if ($result->num_rows >= 2) {
$array;
$i = 1;
while ($row = $result->fetch_array()) {
$array[$i] = $row;
$i++;
}
return $array;
} elseif ($result->num_rows == 1) {
return $result->fetch_array();
}
}
} else {
die("There was an error running the query, throwing error: " . $this->db->error);
}
}
Basically, in short, I took my entire database, deleted it, and remade another one based on the OOD mysqli (using the class mysqli) and reformatted it into a class that extends mysqli. A better look at the full script can be found here:
http://pastebin.com/Bc00hESn
And yes, it does what I want it to. It queries multiple rows, and I can handle them however I wish using the very same methods I planned to do them in. Thank you for the help.
I think you should be using mysql_fetch_assoc():
<?php
while ($row = $db->query($pagination->get_content())) {
print_r($row);
}
?>
i have complex query and say it $complexQuery,
then i need to get all data row number from that without need the data result.
I researched that count_all_results() i better than num_rows()
now say my code :
$complexQuery = 'Some sql query';
$q = $this->db->query($complexQuery);
$total1 = $q->num_rows();
now i confuse to get all total data from that query,
any suggestion for using $this->db->count_all_results() with that query ?
== SOLVED BY EDITING DB_active_rec.php ==
i do this (leave as it is if tablename contained 'select') :
public function from($from)
{
foreach ((array)$from as $val)
{
if (strpos($val, ',') !== FALSE)
{
foreach (explode(',', $val) as $v)
{
$v = trim($v);
$this->_track_aliases($v);
$v = $this->ar_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
if ($this->ar_caching === TRUE)
{
$this->ar_cache_from[] = $v;
$this->ar_cache_exists[] = 'from';
}
}
}
else
{
$val = trim($val);
// Added to bypass from arr if $val contained 'select' for complex query
// $this->db->count_all_rows("select * from tableName")
// will be select count(1) from (select * from tableName)
if(FALSE !== strpos(strtolower($val),'select')){
$this->ar_from[] = "($val)";
}else{
// Extract any aliases that might exist. We use this information
// in the _protect_identifiers to know whether to add a table prefix
$this->_track_aliases($val);
$this->ar_from[] = $val = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
}
if ($this->ar_caching === TRUE)
{
$this->ar_cache_from[] = $val;
$this->ar_cache_exists[] = 'from';
}
}
}
return $this;
}
that should be like:
$this->db->where($complexQuery);
$this->db->from('your_table_name');
echo $this->db->count_all_results();
See: Codeigniter count_all_results()
another minutes, but the same code
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class SomeMyModel extends CI_Model {
private static $db;
function __construct()
{
parent::__construct();
self::$db = &get_instance()->db;
}
static function countTableResults(){
self::$db->where($coplexQuery);
return self::$db->count_all_results('#TABLENAME#');
}
I seem to be having a problem with the below code. I cannot get the insert query to run when the query returns nothing. But when there is a row in the db, the else statement runs correctly. Does anybody know why this could be happening?
$query5 = $this->db->get_where('loggedstatus', array('userid_loggedstatus' => $userid));
if ($query5->num_rows() < 0) {
$data1 = array('isLoggedIn_loggedstatus' => 'yes', 'userid_loggedstatus' => $userid);
$this->db->insert('loggedstatus', $data1);
} else {
$data = array('isLoggedIn_loggedstatus' => 'yes');
$this->db->where('userid_loggedstatus', $userid);
$this->db->update('loggedstatus', $data);
}
Have you tried changing this if ($query5->num_rows() < 0) { to something like if ($query5->num_rows() <= 0) {, just a thought. It would make a difference because your telling it to only execute if its less than zero however it might be equal to zero and you would skip to the else statement.
And just for CodeIgniter num_rows() reference:
/**
* Number of rows in the result set
*
* #return int
*/
public function num_rows()
{
if (is_int($this->num_rows))
{
return $this->num_rows;
}
elseif (count($this->result_array) > 0)
{
return $this->num_rows = count($this->result_array);
}
elseif (count($this->result_object) > 0)
{
return $this->num_rows = count($this->result_object);
}
return $this->num_rows = count($this->result_array());
}
Changing if condition shown below should fix the problem.
if ($query5->num_rows() == 0)