codeigniter : Commands out of sync; you can't run this command now - codeigniter

I applied all the possible answers but still same problem.
also tried
$this->db->reconnect();
there is no problem in my query
MyCode:
public function GetdistributorsDetails($username){
$sql = "SELECT u.FirstName, u.Email, u.Telephone, u.MobileNumber, u.AlternateMobileNumber, ud.Address1, ud.Pincode,ud.City,s.Statename FROM users u JOIN userdetails ud ON ud.UserId = u.UserId JOIN states s ON s.StateId = ud.StateId WHERE u.Username = ? ";
$result = $this->db->query($sql,array($username));
return $result->result_array();
}

add following code into /system/database/drivers/mysqli/mysqli_result.php
function next_result()
{
if (is_object($this->conn_id))
{
return mysqli_next_result($this->conn_id);
}
}
then in model when you call Stored Procedure
$query = $this->db->query("CALL test()");
$res = $query->result();
//add this two line
$query->next_result();
$query->free_result();
//end of new code
return $res;

you can use this after call
mysqli_next_result( $this->db->conn_id );

Here is example if you don't want change any thing in mysqli drivers files
$sql = "CALL procedureName(IntParam,'VarcharParm1','VaracharParm2','VarcharParm3');";
$query = $this->db->query($sql);
mysqli_next_result( $this->db->conn_id );
$query->free_result();
these are important line place after to remove the error
mysqli_next_result( $this->db->conn_id );
$query->free_result();

Just use this one if you use multiple query make in same function:
$this->db->close();

If your stored procedure returns more than one result, try to add this code between the queries:
$storedProcedure = 'CALL test(inputParam, #outputParam)';
$this->db->query($storedProcedure);
$conn = $this->db->conn_id;
do {
if ($result = mysqli_store_result($conn)) {
mysqli_free_result($result);
}
} while (mysqli_more_results($conn) && mysqli_next_result($conn));
$sql = 'SELECT #outputParam;';
$this->db->query($sql);

Just add next_result function in
system\database\drivers\mysqli\mysqli_result.php file
public function next_result(){
if(is_object($this->conn_id) && mysqli_more_results($this->conn_id)){
return mysqli_next_result($this->conn_id);
}
}
To call query function
$result = $this->db->query("CALL {$Name}({$Q})",$Param);
$result->next_result();
return $result;

Related

codeigniter get array data in controller

I have sql query in controller, this query produces number of rows.
$q1 = $this->db->query("SELECT product_code,product_quantity FROM tbl_order_details WHERE order_id='$order_no' AND location='$location'")->row();
foreach($q1 as $v_barcode){
$result = $this->settings_model->update_cancel_stock($v_barcode->product_code,$v_barcode->product_quantity);
}
then i pass this data to my model,
public function update_cancel_stock($code,$qty)
{
$this->db->set('product_quantity', $qty , FALSE);
$this->db->where('product_id', $order );
$this->db->update("tbl_inventory6");
}
but no any update. please check above code. thanx
Try this
$cond = array("order_id" => $order_no, "location" => $location);
$q1 = $this->db->select("product_code,product_quantity")->from("tbl_order_details")->where($cond)->row();
$result = $this->settings_model->update_cancel_stock($q1->product_code,$q1->product_quantity);
and then model ($code was not used)
public function update_cancel_stock($code,$qty){
$this->db->set('product_quantity', $qty , FALSE);
$this->db->where('product_id', $code);
$this->db->update('tbl_inventory6');
}
You are using row() function of Active Record. It already return only one row. So there is no requirement of foreach. Try this:
$q1 = $this->db->query("SELECT product_code,product_quantity FROM tbl_order_details WHERE order_id='$order_no' AND location='$location'")->row();
$result = $this->settings_model->update_cancel_stock($q1->product_code,$q1->product_quantity);
If you are getting multiple records and you are using foreach, you should use result().
$q1 = $this->db->query("SELECT product_code,product_quantity FROM tbl_order_details WHERE order_id='$order_no' AND location='$location'")->result();
foreach($q1 as $v_barcode){
$result = $this->settings_model->update_cancel_stock($v_barcode->product_code,$v_barcode->product_quantity);
}

Use like in join in codeigniter

public function get_rows_set_test( $table, $id_subjects )
{
$this->db->select('id_sets','sets.sets_name');
$this->db->from($table);
$this->db->join('sets', 'sets.id LIKE CONCAT("%",questions.id_sets,"%")');
$this->db->where('id_subjects' , $id_subjects);
$this->db->distinct();
$query = $this->db->get();
if( $query->num_rows() > 0 )
{
foreach( $query->result() as $row ) $rows[] = $row;
return $rows;
}
else return '';
}
its gives this error
Error Number: 1064
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 'LIKE CONCAT("%",questions.id_sets,"%") WHERE id_subjects = '13'' at line 3
SELECT DISTINCT id_sets FROM (questions) JOIN sets ON sets.id LIKE CONCAT("%",questions.id_sets,"%") WHERE id_subjects = '13'
Filename: C:\xampp\htdocs\modeltest\system\database\DB_driver.php
Line Number: 330
error
$this->db->join('sets', 'sets.id LIKE CONCAT("%",questions.id_sets,"%")', false);
Please check below function with join between two tables:
public function get_rows_set_test( $table, $id_subjects )
{
$this->db->select('id_sets','sets.sets_name');
$this->db->from($table);
$this->db->join('sets','sets.id=questions.id_sets');
$this->db->where('id_subjects' , $id_subjects);
$this->db->distinct();
$query = $this->db->get();
if( $query->num_rows() > 0 )
{
foreach( $query->result() as $row ) $rows[] = $row;
return $rows;
}
else return '';
}
You don't need the LIKE there, you are matching the two id I suppose, simple do the following
$this->db->join('sets','sets.id=questions.id_sets');
You could write it as a stored procedure on the database side then use:
`$query = $this->db->query("call stored_procedure()");'
https://codeigniter.com/user_guide/database/call_function.html

Laravel how to get query with bindings?

I have some query that I need to pass to another query using query builder
$query = DB::table('table')->whereIn('some_field', [1,2,30])->toSql();
Model::join(DB::raw("({$query}) as table"), function($join) {
$join->on('model.id', '=', 'table.id');
})
which should results with
Select * from model join (select * from table where some_field in (1,2,30)) as table on model.id = table.id
but the bindings are not passed, which force me to do
$query = DB::table('table')->whereRaw('some_field in ('. join(',', [1,2,30]) .')')->toSql();
what can be unsafe at times. How can I get the query with bindings?
Check out the getBindings() method on the Builder class
getBindings()
$query = DB::table('table')->whereIn('some_field', [1,2,30]);
$sql = $query->toSql();
$bindings = $query->getBindings();
Laravel now offers debugging directly on your Builder!!!
https://laravel.com/docs/queries#debugging
\App\User::where('age', '18')->dump();
\App\User::where('age', '18')->dd();
Outputs
"select * from `users` where `age` = ?"
[
0 => "18"
]
public static function getQueries(Builder $builder)
{
$addSlashes = str_replace('?', "'?'", $builder->toSql());
return vsprintf(str_replace('?', '%s', $addSlashes), $builder->getBindings());
}
You can define below code block as helper function and use wherever required.
It will bind numeric as well as string value with quotations.
public static function getSqlWithBindings($query)
{
return vsprintf(str_replace('?', '%s', $query->toSql()), collect($query->getBindings())->map(function ($binding) {
return is_numeric($binding) ? $binding : "'{$binding}'";
})->toArray());
}
Example:
$query = Document::where('model', 'contact')->where('model_id', '1');
dd(Document::getSqlWithBindings($query));
Output:
"select * from `document` where `model` = 'contact' and `model_id` = 1"
Building upon Douglas.Sesar's answer.
I found I also needed to put the bindings in single quotations to be able to easily paste it into my database IDE.
$sql = $query->toSql();
$bindings = $query->getBindings();
$sql_with_bindings = preg_replace_callback('/\?/', function ($match) use ($sql, &$bindings) {
return json_encode(array_shift($bindings));
}, $sql);
$sqlQuery = Str::replaceArray(
'?',
collect($query->getBindings())
->map(function ($i) {
if (is_object($i)) {
$i = (string)$i;
}
return (is_string($i)) ? "'$i'" : $i;
})->all(),
$query->toSql());
The following function ensures the resulting SQL doesn't confuse bindings with columns by enclosing the ? to be '?'
public static function getFinalSql($query)
{
$sql_str = $query->toSql();
$bindings = $query->getBindings();
$wrapped_str = str_replace('?', "'?'", $sql_str);
return str_replace_array('?', $bindings, $wrapped_str);
}
If you want to get an executed query including bindings from the query log:
\DB::enableQueryLog();
\DB::table('table')->get();
dd(str_replace_array('?', \DB::getQueryLog()[0]['bindings'],
\DB::getQueryLog()[0]['query']));
I created this function. It is partial, might be parameters which are not covered, for me it was enough.
More than welcomed to add your improvements in a comment!
function getFullSql($query) {
$sqlStr = $query->toSql();
foreach ($query->getBindings() as $iter=>$binding) {
$type = gettype($binding);
switch ($type) {
case "integer":
case "double":
$bindingStr = "$binding";
break;
case "string":
$bindingStr = "'$binding'";
break;
case "object":
$class = get_class($binding);
switch ($class) {
case "DateTime":
$bindingStr = "'" . $binding->format('Y-m-d H:i:s') . "'";
break;
default:
throw new \Exception("Unexpected binding argument class ($class)");
}
break;
default:
throw new \Exception("Unexpected binding argument type ($type)");
}
$currentPos = strpos($sqlStr, '?');
if ($currentPos === false) {
throw new \Exception("Cannot find binding location in Sql String for bundung parameter $binding ($iter)");
}
$sqlStr = substr($sqlStr, 0, $currentPos) . $bindingStr . substr($sqlStr, $currentPos + 1);
}
$search = ["select", "distinct", "from", "where", "and", "order by", "asc", "desc", "inner join", "join"];
$replace = ["SELECT", "DISTINCT", "\n FROM", "\n WHERE", "\n AND", "\n ORDER BY", "ASC", "DESC", "\n INNER JOIN", "\n JOIN"];
$sqlStr = str_replace($search, $replace, $sqlStr);
return $sqlStr;
}
You can do something like this:
$escapedBindings = array();
foreach($query->getBindings() as $item) {$escapedBindings[] = '"'.$item.'"';}
$sql_with_bindings = Str::replaceArray('?', $escapedBindings, $query->toSql());
This is a very old question (2015), but since this is the first Google result I got I think it's worth to give my solution as well, in case it's useful for the next person.
Eloquent (5.7 onwards I think, I haven't tested more recent or earlier versions) has a method to change a Builder's from to wrap a subquery:
# Taken from Illuminate/Database/Query/Builder.php - Line 272
public function fromSub($query, $as) {
[$query, $bindings] = $this->createSub($query);
return $this->fromRaw('('.$query.') as '.$this->grammar->wrapTable($as), $bindings);
}
This however requires an already existing instance of \Illuminate\Database\Query\Builder. In order to make an empty one, you can do:
use Illuminate\Database\Capsule\Manager as DB;
$fancy = DB::table("videogames")->where("uses_sdl2", 1);
$empty = DB::table(null);
# Wrap the fancy query and set it as the "from" clause for the empty one
# NOTE: the alias is required
$empty = $empty->fromSub($fancy, "performant_games");
This will warranty that bindings are treated correctly, since they'll be handled by Eloquent itself.
Since the other answers do not properly quote the expressions, here is my approach. It uses the escaping function that belongs to the current database connection.
It replaces the question marks one by one with the corresponding binding, which is retrieved from $bindings via array_shift(), consuming the array in the process. Note, that $bindings has to be passed by reference for this to work.
function getSql($query)
{
$bindings = $query->getBindings();
return preg_replace_callback('/\?/', function ($match) use (&$bindings, $query) {
return $query->getConnection()->getPdo()->quote(array_shift($bindings));
}, $query->toSql());
}
Simple and elegant solution:
foreach (DB::getQueryLog() as $q) {
$queryStr = \Str::replaceArray('?', $q['bindings'], $q['query']);
echo $queryStr . ";\n";
}
(if you use a non-default connection, use DB::connection('yourConn')->getQueryLog() in the foreach command).
Output to the log all queries with inserted bindings sorted from the slowest query to the fastest:
\DB::enableQueryLog();
// Put here your queries
$query = DB::table('table')->whereIn('some_field', [1,2,30]);
$query2 = DB::table('table2')->where('some_field', '=', 10);
$logQueries = \DB::getQueryLog();
usort($logQueries, function($a, $b) {
return $b['time'] <=> $a['time'];
});
foreach ($logQueries as $item) {
\Log::info(str_replace_array('?', $item['bindings'], $item['query']));
\Log::info($item['time']. ' ms');
}
It is all explained here.....
https://ajcastro29.blogspot.com/2017/11/laravel-join-derived-tables-properly.html
I created a scope query for that thing. I think it can also be in macros..
public function scopeJoinDerived($query, $derivedQuery, $table, $one, $operator = null, $two = null, $type = 'inner', $where = false)
{
$query->join(DB::raw("({$derivedQuery->toSql()}) as `{$table}`"), $one, $operator, $two, $type, $where);
$join = last($query->getQuery()->joins);
$join->bindings = array_merge($derivedQuery->getBindings(), $join->bindings);
return $query;
}

codeigniter - compare values

I need to compare two values in a table: cliente and nro_cuota, if both exist I don't want to add it.
Here is my code
$crud = new grocery_CRUD();
$crud->set_theme('datatables');
$crud->set_table('cobranzas');
$crud->set_subject('Cobranzas');
$crud->set_language('spanish');
$crud->required_fields(
'id',
'cobrador',
'cliente',
'nro_cuota'
);
$crud->columns(
'cobrador',
'cliente',
'nro_cuota'
);
$crud->set_relation('cobrador', 'cobradores', 'apellido_nombre');
$crud->set_relation('cliente', 'clientes', 'apellido_nombre');
$output = $crud->render();
$this->load->view('cobranzas/cobranzas_v', $output);
}catch(Exception $e){
show_error($e->getMessage().' --- '.$e->getTraceAsString());
}
}
and I wrote a model, I`m not sure if this is the right way, but I don't know how I must call it
class Compare_values_model extends CI_Model
{
public function compare($id)
{
$this->db->select('"SELECT * FROM `cobranzas` WHERE `cliente` = '$cliente' AND `nro_cuota` = '$nro_cuota'"');
if ($query->num_rows() > 0) {
return true;
} else {
return false;
}
}
}
Hope can help me I couldn't find some examples on internet to learn more, thanks in advance.
You said I need to compare two values in a table: cliente and nro_cuota, if both exist I don't want to add it. But you are matching the variables with fields. So just check not equal as below:
$query = $this->db->query("SELECT * FROM `cobranzas` WHERE `cliente` <> '$cliente' AND `nro_cuota` <> '$nro_cuota'");
Note: Remove extra single quote in your query

Codeigniter: Can I return multiple values from the same function?

I would like to return the query results along w/ the row count without having to run multiple queries. Is this possible in Codeigniter? The following works for returning the query results, but is it possible to also count the number of entries found?
Controller:
$data['records'] = $this->item_model->searchItem($item_name);
Model:
$query = $this->db->query($sql, array($this->user_id, '%'.$item_name.'%'));
return $query->result();
$bindings = array($this->user_id, '%'.$item_name.'%');
$records = $this->db->query($sql, $bindings)->result();
return array(
'records' => $records,
'count' => count($records),
);
Then, in your controller:
$query = $this->item_model->searchItem($item_name);
$data['records'] = $query['records'];
$data['count'] = $query['count'];
Option one
$query = $this->db->query($sql, array($this->user_id, '%'.$item_name.'%'));
$data['result'] = $query->result();
$data['rows'] = $query->num_rows();
return $data;
Option two
// model
$query = $this->db->query($sql, array($this->user_id, '%'.$item_name.'%'));
return $query;
// controller
$data['query'] = $this->item_model->searchItem($item_name);
// then you have $data['query']->result();
// and $data['query']->num_rows();
You can send as many variables from a function as you want ..However plz remember that a function is supposed to do one UNIT of work . thus this rule must not be violated.
we can used contrel structure
if this {return A;} elseif () {return B;} else {return C;}
ALso we can send (bundle) variables in an array and send

Resources