gpt4 book ai didi

yii2 - 使用存储过程保存到多个表中

转载 作者:行者123 更新时间:2023-12-04 02:16:23 27 4
gpt4 key购买 nike

我有 2 个模型:ReceivedGoodsDetailStockInventory

当模型 ReceivedGoodsDetail 执行 actionCreate 时,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,
]);
}
}

但如果像上面的情况那样使用 2 个模型,我会感到困惑

最佳答案

不要害怕做这样的事情,在这里使用存储过程也没什么不好。但总的来说,您的代码并不干净而且相当困惑。

首先,如果您使用的是存储过程,那么为什么不为 ReceivedGoodsDetail 创建一个触发器(在 INSTERT 上)?恕我直言,使用触发器一切都会简单得多。

以下是对您的实现的一些说明。

  1. 为什么要在第一个 if 之前打开交易?如果验证失败,那么您的交易将不会关闭手动。
  2. 我在这里看不到使用 2 个模型,只有一个 - ReceivedGoodsDetailStockInventory据我所知,将在存储过程 usp_T_Received_Goods_Detail#InsertData?
  3. 中创建
  4. 为什么即使交易失败,您仍将用户重定向到项目 View ?
  5. 使用 ActiveRecord。那么这里就不需要手动开始交易了。只需定义什么操作您希望在 transactions() 中成为此模型的交易对象方法。
  6. 使用 ActiveRecord。更好的做法是从您的模型类而不是应用程序获取数据库连接。默认情况下它将是 Yii::$app->db,但稍后您可以轻松更改此特定模型的连接。

(例如)扩展 ActiveRecord(如果还没有)并重载 insertInternal() 方法会更好对于 ReceivedGoodsDetail

在类 ReceivedGoodsDetail 中:

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,
]);
}
}

然后在创建表单上捕捉您的即时消息。

附言再等一会。使用 path/to/model/{id} 端点是一种奇怪的做法使用预定义的 ID 创建新实例。通常这看起来像 POST path/to/model。但这可能是你业务逻辑的主题,所以我不知道它是否可以改进

附言这个例子没有经过测试(很明显)所以这里可能有一些错误

关于yii2 - 使用存储过程保存到多个表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38393430/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com