DATEDIFF in YII MYSQL - mysql

$criteria = new CDbCriteria();
$criteria->addCondition(array('where' => 'select DATEDIFF(CURDATE(),t.due_date) < 0'));
$dataProvider = new CActiveDataProvider('Loan', array(
'criteria' => $criteria
));
$this->render('index', array(
'dataProvider' => $dataProvider,
));
This is my code, I want to retreive all data from 'Loan' model with some criteria, but I found problem like so:
CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1305 FUNCTION libraryng.DATEDIFF does not exist. The SQL statement executed was: SELECT COUNT(*) FROM `loans` `t` WHERE (select DATEFIFF(CURDATE(),t.due_date) < 0)
I hope someone can help me.

change this line to
$criteria->condition('DATEDIFF(CURDATE(),`t`.due_date) < 0');

Related

Getting a raw SQL query with variables in Yii1

Is Yii1 has any native methods to get the raw SQL with variables built?
I try to get a complex query built on a few subqueries using CDbExpression and CommandBuilder. I got this as a result:
SELECT * FROM `news` `t` WHERE id IN (:ycp0, :ycp1, :ycp2, :ycp3, :ycp4) LIMIT 5
The dump of the criteria content:
CDbCriteria Object (
[select] => *
[condition] => id IN (:ycp0, :ycp1, :ycp2, :ycp3, :ycp4)
...
[params] => Array(
[:ycp0] => CDbExpression Object(
[expression] => SELECT id FROM `news` `t` WHERE (rubric=:rb1) AND (:im2 & `im`=:im2) LIMIT 1
[params] => Array(
[:rb1] => 1
[:im2] => 2
)
)
...
)
)
I expected for compiled query string like this:
SELECT * FROM .. WHERE id IN(
(SELECT id FROM .. WHERE .. ORDER BY .. LIMIT 1),
(SELECT id FROM .. WHERE .. ORDER BY .. LIMIT 1)
) ORDER BY .. LIMIT 5
This is what I do in my code
$criteria = new CDbCriteria( ... );
$sql = $this->commandBuilder->createFindCommand($tableName, $criteria)->getText();
$queries[] = new CDbExpression($sql, $criteria->params);
Then I try to combine subqueries to one complex query
$criteria = new CDbCriteria( ... );
$criteria->addInCondition('id', $queries);
And finally, I try to get the result as SQL-query
$sql = $this->commandBuilder->createFindCommand($tableName, $criteria)->getText();
You get the SQL with params, as you have
$sql = $this->commandBuilder->createFindCommand($tableName, $criteria)->getText();
Then get the params enclosed in quotes:
$params = array_map(function($param) { return '"' . $param . '"'; }, $criteria->params);
Finally, replace the pairs:
echo strtr($sql, $params);
You can use enableParamLogging in your db config (boolean). You can set it up so it's used conditionally -- make sure to not use it in production.
'db' => [
'connectionString' => 'mysql:host=' . $dbhost . ';port=' . $dbport . ';dbname=' . $dbname,
'emulatePrepare' => true,
'username' => $db_user,
'password' => $db_pass,
'schemaCachingDuration' => 3600,
'charset' => 'utf8',
'enableProfiling' => $db_profile,
'enableParamLogging' => $db_params,
],
Then you can add 'class'=>'CWebLogRoute' to your log routes if you want to see all the output in your browser. docs
I think you want to do something like this:
$criteria = ...;
$command = $builder->createFindCommand($schema->getTable('name_of_table'), $criteria);
$results = $command->text;
There are few other options to perform the same thing but i will suggest you
should use the following
$results = MyModel::model()->findAllBySql("...");
Or you can prefer the following :
Sub-queries ActiveRecord Yii

Joomla! (with K2) MySql - Error when generating

I dont get it ... I tested a lot but dont get why a SQL error appears ...
In my case I use a function to generate a mysql-query to get all extra-field items from the database (K2 - Component).
It is used like this:
public static function readExtraFields ($fields, $as = 'array') {
if (!is_array($fields)) $fields = json_decode($fields);
$result = array();
$whereId = array();
$allFieldValues = array();
foreach ($fields as $field) {
$whereId[] = "`id`='".$field->id."'";
$allFieldValues[$field->id] = $field->value;
}
$query = "SELECT * FROM `#__k2_extra_fields` WHERE " . implode(" OR ", $whereId);
$queryResult = self::execQuery($query);
[...]
In this method a query will be generated like this (I printed it out)
SELECT * FROM `#__k2_extra_fields` WHERE `id`='1' OR `id`='2'
This is fine. When I execute the methode execQuery with the given query this error appears:
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 '' at line 1 SQL=SELECT * FROM `j7req_k2_extra_fields` WHERE
Thats all ... I dont get it. My method to execute my mysql-query:
public static function execQuery ($query) {
$db = JFactory::getDbo();
$db->setQuery($query);
$result = $db->loadObjectList();
return $result;
}
For testing I printed out the Query (the above) and set $query to the printed query and this runs without any problems like the way it should work ... So the query which is given is right ... what can be the problem ?
Edit 1
In my execQuery method I printed the $db out. This reuslt is given (you can find the query at the bottom of this object)
JDatabaseDriverMysqli Object
(
[name] => mysqli
[nameQuote:protected] => `
[nullDate:protected] => 0000-00-00 00:00:00
[_database:JDatabaseDriver:private] => podopraxis
[connection:protected] => mysqli Object
(
[affected_rows] => 1
[client_info] => mysqlnd 5.0.11-dev - 20120503 - $Id: bf9ad53b11c9a57efdb1057292d73b928b8c5c77 $
[client_version] => 50011
[connect_errno] => 0
[connect_error] =>
[errno] => 0
[error] =>
[error_list] => Array
(
)
[field_count] => 1
[host_info] => localhost via TCP/IP
[info] =>
[insert_id] => 0
[server_info] => 5.6.16
[server_version] => 50616
[stat] => Uptime: 48979 Threads: 1 Questions: 6461 Slow queries: 0 Opens: 163 Flush tables: 1 Open tables: 155 Queries per second avg: 0.131
[sqlstate] => 00000
[protocol_version] => 10
[thread_id] => 203
[warning_count] => 0
)
[count:protected] => 45
[cursor:protected] =>
[debug:protected] =>
[limit:protected] => 0
[log:protected] => Array
(
)
[timings:protected] => Array
(
)
[callStacks:protected] => Array
(
)
[offset:protected] => 0
[options:protected] => Array
(
[driver] => mysqli
[host] => localhost
[user] => root
[password] =>
[database] => podopraxis
[prefix] => j7req_
[select] => 1
[port] => 3306
[socket] =>
)
[sql:protected] => SELECT * FROM `#__k2_extra_fields` WHERE `id`='1' OR `id`='2'
[tablePrefix:protected] => j7req_
[utf:protected] => 1
[errorNum:protected] => 0
[errorMsg:protected] =>
[transactionDepth:protected] => 0
[disconnectHandlers:protected] => Array
(
)
)
It looks like your query fired in execQuery() function is missing the condition statement after "WHERE" clause of query.
Please make sure below part of condition comes in your query:
`id`='1' OR `id`='2'
let me know if I am not getting well about your question?
Also try to post here whole $db object by printing as below:
echo "<pre />";print_r($db);exit;

Pagination using joining multiple models

Each exam has one syllabus, each syllabus has one exam. So, I did this in the Exam model:
public $hasOne = 'Syllabuses'; //table: syllabuses, model: Syllabuses
From UsersController I did this:
public $uses = array('Setting', 'Exam', 'Syllabuses');
And in a method in UsersController I wanted to call paginate:
$options = array(
'fields' => array('Exam.id', 'Exam.name', 'Syllabuses.id', 'Syllabuses.name', 'Syllabuses.syllabus', 'Syllabuses.last_updated'),
'joins' => array(
'table' => 'syllabuses',
'conditions' => array('Exam.id = Syllabuses.exam_id')
)
);
$this->paginate = $options;
$this->set('syllabuses', $this->Paginator->paginate('Syllabuses'));
exams table:
---+------+
id | name |
---+------+
and syllabuses table:
---+---------+------+----------+--------------+
id | exam_id | name | syllabus | last_updated |
---+---------+------+----------+--------------+
So, I got some error. Like this:
Error: SQLSTATE[42000]: Syntax error or access violation: 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 'syllabuses Array LEFT JOIN oes.syllabuses AS Syllabuses ON (Syllabuses.`' at line 1
And my SQL that CakePHP prepared is:
SELECT `Exam`.`id`, `Exam`.`name`, `Syllabuses`.`id`, `Syllabuses`.`name`, `Syllabuses`.`syllabus`, `Syllabuses`.`last_updated`
FROM `oes`.`exams` AS `Exam` syllabuses Array
LEFT JOIN `oes`.`syllabuses` AS `Syllabuses` ON (`Syllabuses`.`exam_id` = `Exam`.`id`)
WHERE 1 = 1 LIMIT 20
But what I want is something like the query bellow. I have tested it in mysql:
SELECT `Exam`.`id` AS eid, `Exam`.`name` AS ename, `Syllabuses`.`id` AS sid, `Syllabuses`.`name` AS sname, `Syllabuses`.`syllabus` , `Syllabuses`.`last_updated`
FROM `oes`.`syllabuses` AS `Syllabuses` , exams AS Exam
WHERE Exam.id = Syllabuses.exam_id
ORDER BY Exam.id
LIMIT 20
Now anybody please help me achieve this. What kind of change can make CakePHP to prepare query like that(what I've tasted) to make my Pagination done.
Ok, I think this can be helpful for many programmers. That's why I want to share what I did finally:
$options = array(
'fields' => array(
'Exam.id',
'Exam.name',
'Syllabuses.id',
'Syllabuses.name',
'Syllabuses.exam_id',
'Syllabuses.syllabus',
'Syllabuses.last_updated'
),
'recursive' => 0,
'conditions' => array('Exam.id = Syllabuses.exam_id'),
'limit' => 3
);
$this->paginate = $options;
$syllabuses = $this->Paginator->paginate('Exam');

Zend DB Union Error

I have two query:
$select1 = $this->select()
->from(array('o'=>'table1'), array('*', 'o.field2 AS shared'))
->where('field4= ?', $input);
$select2 = $this->select()
->from(array('i'=>'table2'), array('*', 'ch.field1 AS shared'))
->where('ch.field5= ?', $input);
Both query works successfully. However, it does not work with the following union function even with shared parameter name. How come?
//Merge both query
$selectboth = $this->select()
->union(array($select1, $select2))
->order('shared');
$obj = $this->dbo->fetchRow($selectboth);
I am suspecting my fetchRow is the one causing this error in fetching.
if you have number of column same in both sql so you can ran into this issue:
http://framework.zend.com/issues/browse/ZF-4338
for example:
$select_q1 = $db->select()->...;
$select_q2 = $db->select()->...;
$main_select = $db->select()->union( array( '('.$select_q1 .')', '('.$select_q2 .')' ) );

Database Error Occurred Error Number: 1062

i tried to make option update three table with one execution for my CI with sql there, but why its still error?
this is the error warning:
A Database Error Occurred
Error Number: 1062
Duplicate entry '0' for key 1
UPDATE `t_publisher` SET `id_publisher` = NULL, `publisher` = NULL, `artis` = NULL, `id_label` = NULL WHERE `id_publisher` = '113'
this is the code:
function update($id_user=null)
{
if (($this->input->post('submit') == 'Update')){
$user=$this->input->post('username');
$pass=$this->input->post('userpassword');
$ussta=$this->input->post('userstatus');
$usty=$this->input->post('usertype');
$data = array(
'user_name' => $user,
'user_pass' => $pass,
'user_status' => $ussta,
'user_type' => $usty);
$this->db->where('user_id', $this->input->post('id'), $data);
$this->db->update("t_user",$data);
$data1 = array(
'id_publisher' => $id_publis,
'publisher' => $publis,
'artis' => $ar,
'id_label' => $id_lab);
$this->db->where('id_publisher', $this->input->post('id'), $data);
$this->db->update("t_publisher",$data1);
echo $this->db->last_query();
die();
$data2 = array(
'id_label' => $id_lab,
'label' => $label);
$this->db->where('id_label', $this->input->post('id'), $data);
$this->db->update("t_label",$data2);
echo $this->db->last_query();
die();
redirect("registrasi/reg");
}
$var['data'] = $this->db->query("select * from t_user where USER_ID= '$id_user'")->row_array();
$var1['data'] = $this->db->query("select * from t_publisher where id_publisher = '$id_publis'")->row_array();
$var2['data'] = $this->db->query("select * from t_label where id_label = '$id_lab'")->row_array();
$this->load->view('update', $var,$var1,$var2);
}
whats wrong with my code? please help. thanks before.
Your UPDATE clause is setting the id_publisher column to NULL, and, based on the name of the column and the error you're receiving, that column is the table's PRIMARY KEY with a setting of unsigned NOT NULL.
Because of this, when you do id_publisher = NULL, MySQL converts it to id_publisher = 0 due to the unsigned part. This will execute fine the first time, however, when you run it on a second row you will now be attempting to insert a second primary-key value of 0, which is not allowed.
Based on the location of the die() statement in your sample code, I'm assuming the following block is the culprit:
$data1 = array(
'id_publisher' => $id_publis,
'publisher' => $publis,
'artis' => $ar,
'id_label' => $id_lab);
$this->db->where('id_publisher', $this->input->post('id'), $data);
$this->db->update("t_publisher",$data1);
Here, your $id_publis variable is either empty or null.
I would suggest to either remove the id_publisher = NULL portion from the UPDATE clause which is as simple as removing 'id_publisher' => $id_publis, from the $data1 array, or rethink the reason you actually need to set it to null to begin with (in this case, would deleting the row be more beneficial?)