Yii2 使用存储过程保存到多个表中
我有两种型号:Yii2 使用存储过程保存到多个表中,yii2,Yii2,我有两种型号:receivedGoodDetail和StockInventory 当modelReceivedGoodDetailDoActionCreate时,StockInventory也会自动插入表StockInventory 我使用这个存储过程,这是我尝试过的: public function actionCreate($id) { $model = new ReceivedGoodsDetail(); $connection = \Yii::$app->db; $transact
receivedGoodDetail
和StockInventory
当modelReceivedGoodDetail
DoActionCreate时,StockInventory
也会自动插入表StockInventory
我使用这个存储过程,这是我尝试过的:
public function actionCreate($id) {
$model = new ReceivedGoodsDetail();
$connection = \Yii::$app->db;
$transaction = $connection->beginTransaction();
$model->ID_Received_Goods = $id;
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$connection = Yii::$app->db;
$command = $connection->createCommand('{call usp_T_Received_Goods_Detail#InsertData(:ID_Received_Goods,:ID_Item, :Qty, :User)}');
$ID_Received_Goods = $model->ID_Received_Goods;
$ID_Item = $model->ID_Item;
$Qty = $model->Qty;
$User = Yii::$app->user->identity->username;
$command->bindParam(":ID_Received_Goods",$ID_Received_Goods,PDO::PARAM_STR);
$command->bindParam(":ID_Item", $ID_Item, PDO::PARAM_STR);
$command->bindParam(":Qty", $Qty, PDO::PARAM_INT);
$command->bindParam(":User", $User, PDO::PARAM_STR);
if ($command->execute() == 0) {
$transaction->commit();
} else {
$transaction->rollBack();
foreach ($model->getErrors() as $key => $message) {
Yii::$app->session->setFlash('error', $message);
}
}
return $this->redirect(['receivedgoodsheader/view', 'id' => $model->ID_Received_Goods]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
但是,如果使用上述两种模型,我会感到困惑。不要害怕这样做,这里使用存储过程并没有什么不好的。但一般来说,您的代码并不干净,也不容易理解 首先,如果您使用的是存储过程,那么为什么不为ReceivedGoodDetail(在Insert上)创建一个触发器呢?我想用触发器一切都会简单得多 下面是一些关于您的实现的评论
之前打开交易?如果验证失败,您的交易将不会关闭
手动
receivedGoodDetail
,和StockInventory
据我所知,将在存储过程usp_T_Received_Goods_Detail#InsertData
中创建Yii::$app->db
,但稍后您可以轻松更改此特定型号的连接insertInternal()
方法
对于receivedGoodDetail
在类receivedGoodDetail
中:
public function transactions() {
return [
'default' => self::OP_INSERT
];
}
protected function insertInternal($attributeNames = null) {
if (!$this->beforeSave(true)) {
return false;
}
$values = $this->getDirtyAttributes($attributes);
/* overrided part of code */
$connection = static::getDb();
$command = $connection->createCommand('{call usp_T_Received_Goods_Detail#InsertData(:ID_Received_Goods,:ID_Item, :Qty, :User)}');
$ID_Received_Goods = $model->ID_Received_Goods;
$ID_Item = $model->ID_Item;
$Qty = $model->Qty;
$User = Yii::$app->user->identity->username;
$command->bindParam(":ID_Received_Goods",$ID_Received_Goods,PDO::PARAM_STR);
$command->bindParam(":ID_Item", $ID_Item, PDO::PARAM_STR);
$command->bindParam(":Qty", $Qty, PDO::PARAM_INT);
$command->bindParam(":User", $User, PDO::PARAM_STR);
if($command->execute() != 0) {
return false;
}
/* end of overrided part */
$changedAttributes = array_fill_keys(array_keys($values), null);
$this->setOldAttributes($values);
$this->afterSave(true, $changedAttributes);
return true;
}
在你的行动中:
public function actionCreate($id) {
$model = new ReceivedGoodsDetail();
$model->ID_Received_Goods = $id;
if ($model->load(Yii::$app->request->post()) && $model->save(true)) {
return $this->redirect(['receivedgoodsheader/view', 'id' => $model->ID_Received_Goods]);
} else {
foreach ($model->getErrors() as $key => $message) {
Yii::$app->session->setFlash('error', $message);
}
return $this->render('create', [
'model' => $model,
]);
}
}
然后在创建表单上捕获您的flash消息
还有一分钟。使用path/to/model/{id}
endpoint是一种奇怪的做法
使用预定义的ID
创建新实例。通常这看起来像POST path/to/model
。但这可能是您的业务逻辑的主题,所以我不知道是否可以改进
p.p.S.这个例子没有经过测试(显然),所以这里可能有一些错误你有什么问题?我不明白