I want to add record to a table with ActiveRecord
.
Here is my code:
$model = new Article();
$model->title = 'test title';
$model->content = 'test content';
$model->category_id = 1;
$model->author_id = 1;
if ($model->validate()) {
$model->save();
}
$model->validate()
returns true
, but $model->save()
returns false
.
How to find generated raw sql of $model->save()
?
Meanwhile:
$model->save()->rawSql
is null
and $model->getErrors()
returns empty array.
In debug, all queries are logged, but I did not find any insert or update query.
Call yii\db\QueryBuilder to generate a SQL statement based on the current construct of yii\db\Query; Create a yii\db\Command object with the generated SQL statement; Call a query method (e.g. queryAll()) of yii\db\Command to execute the SQL statement and retrieve the data.
use createcommand() method: use yii\db\Query(); $connection = \Yii::$app->db; $query = new Query; $insql = $connection->createCommand("SELECT* FROM inventory ); $result=$insql->queryAll(); the above method list all data from the inventory table.
Yii2 will use "IS NULL" if the $values === null , but in case the value is supplied as an array, and one of those array elements is null, it will not get any special treatment, resulting in the query never matching any records with NULL value.
To delete a single row of data, first retrieve the Active Record instance corresponding to that row and then call the yii\db\ActiveRecord::delete() method. $customer = Customer::findOne(123); $customer->delete(); You can call yii\db\ActiveRecord::deleteAll() to delete multiple or all rows of data.
$model->save()->rawSql
call can not return null
, it must throw an exception that you are trying to access property of non-object. $model->save()
returns boolean
value - either query executed successfully or not.
If $model->getErrors()
returns empty array and query was not executed at all I'm pretty sure that something is wrong with model event handlers, especially beforeSave()
, check it, it should not return false
. Also check attached behaviors event handlers.
As for getting query. It's useless if it simply was not executed, but if it was, here are some ways to achieve it:
1) Probably the best way. Use debug panel. I also mentioned it here.
2) Look at logs as @robsch adviced.
You can't directly get raw SQL in code with $model->save()
, It will call either insert()
or update()
. If you are interested, here is the part of code for insertInternal()
:
$values = $this->getDirtyAttributes($attributes);
if (empty($values)) {
foreach ($this->getPrimaryKey(true) as $key => $value) {
$values[$key] = $value;
}
}
$db = static::getDb();
$command = $db->createCommand()->insert($this->tableName(), $values);
if (!$command->execute()) {
return false;
}
If you call $command->rawSql
you will get raw sql but you can't do that outside because the command is formed internally.
P.S. This piece of code:
if ($model->validate()) {
$model->save();
}
doesn't make sense because $model->save()
will call $model->validate()
internally.
This code won't show you exactly the raw sql but you'll get the query pre binding and the params
try {
// this will simulate $model->save();
$builder = $model->getCommandBuilder();
$table = $model->getTableSchema();
$command = $builder->createInsertCommand($table, $model->getAttributes());
$command->_connection->enableParamLogging = true;
$command->execute();
} catch (Exception $e) {
// getText() will print the query with the binding params
// getAttributes() will give you the attributes injected
var_dump($command->getText());
var_dump($model->getAttributes());
die();
}
The result will look like:
"INSERT INTO `fruit` (`order`, `name`, `season`) VALUES (:yp0, :yp1,:yp2)"
array(2) {
["order"] => int(1),
["name"] => null,
["season"] => null
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With