質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

Q&A

解決済

2回答

1467閲覧

DBのテーブルの上書きでのトランザクションがうまくいきません MYSQL

kaito2414

総合スコア11

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

0グッド

0クリップ

投稿2020/05/11 06:40

DBのテーブルの上書きでのトランザクションがうまくいきません

CSVを読み込み、DBのテーブルを上書きするものを作成しているのですが、途中でエラーがおこってもトランザクションが働かず、
$del = "DELETE FROM ".$table_name;
$dbh->query($del);
この処理のみ通ってしまいます。
どうすればうまく上書きができますか?

それとも、インサートよりも、UPDATE又はREPLACEのほうがいいですか?
(テーブルにデータがあれば上書き、なければインサート)という風にしたいです。
プライマリキーは設定していません。
idはオートインクリメント

php

1<?php 2// DB情報 3$dbh = null; 4$db_admin = "sbiccicms_admin_local_auto"; 5$db_common = "sbiccicms_common_local_auto"; 6$db_front = "sbiccicms_front_local_auto"; 7$user = 'root'; 8$pass = ''; 9 10// URlファイルパス取得 11$get_dir = __FILE__; 12$get_dir_path = dirname($get_dir); 13$csv_path = glob($get_dir_path.'/categoris/categori.csv'); 14$csv_color = glob($get_dir_path.'/categoris/category_colors.csv'); 15 16$table_name = "categories"; 17 18try { 19 // DB接続 20 $dbh = new PDO('mysql:host=127.0.0.1; dbname='. $db_front.'; charset=utf8', $user, $pass); 21 22 $sql = "SET AUTOCOMMIT=0" ; 23 $dbh->query($sql); 24 25 //例外処理を投げる(スロー)ようにする 26 $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 27 28 // トランザクション開始 29 $dbh->beginTransaction(); 30 31 $del = "DELETE FROM ".$table_name; 32 $dbh->query($del); 33 $auto_reset = "ALTER TABLE ".$table_name." auto_increment = 1;"; 34 $dbh->query($auto_reset); 35 36 // color読み込み 37 if (($handle_color = fopen($csv_color[0], "r")) !== FALSE) { 38 // ファイルポインタ有効時 39 $color = []; 40 while ($handle_color && !feof($handle_color)) { 41 $input_color = fgetcsv($handle_color); 42 if (!$input_color) { 43 continue; 44 } 45 46 // エンコード 47 if ($input_color[1]==="") { 48 continue; 49 } 50 $input_color[1] = mb_convert_encoding($input_color[1], 'UTF-8', 'SJIS-win'); 51 $color[] = $input_color[1]; 52 } 53 } 54 fclose($handle_color); 55 56 // CSVファイルインサート準備 57 $insert = "INSERT INTO ".$table_name." (site_id, parent_id, name, pass, sort, level, color, user_id, created) VALUES (:site_id, :parent_id, :name, :pass, :sort, :level, :color, :user_id, cast(now() as datetime))"; 58 $insert_start = $dbh->prepare($insert); 59 if (!$insert_start) { 60 throw new Exception('インサート準備失敗'); 61 } 62 63 64 // CSVファイルインサート 65 if (($handle = fopen($csv_path[0], "r")) !== FALSE) { 66 // ファイルポインタ有効時 67 $title_skip = 0; 68 $co = 1; 69 while ($handle && !feof($handle)) { 70 $input_csv = fgetcsv($handle); 71 if ($title_skip < 2) { 72 $title_skip++; 73 continue; 74 } 75 if (!$input_csv) { 76 continue; 77 } 78 79 // エンコード 80 $count_input_csv = count($input_csv); 81 for ($i=1;$i<$count_input_csv;$i++) { 82 if ($input_csv[$i]==="") { 83 continue; 84 } 85 $input_csv[$i] = mb_convert_encoding($input_csv[$i], 'UTF-8', 'SJIS-win'); 86 } 87 88 // 実行 89 $synonyms_check = $insert_start->execute([':site_id' => $input_csv[1], ':parent_id' => $co, ':name' => $input_csv[3], ':pass' => $input_csv[4], ':sort' => $input_csv[5], ':level' => $input_csv[6], ':color' => $color[$co], ':user_id' => $input_csv[8]]); 90 if (!$synonyms_check) { 91 throw new Exception('インサート失敗'); 92 } 93 $co++; 94 } 95 } 96 97 // 接続終了 98 fclose($handle); 99 $insert_start = null; 100 101 // エラー // 102 $insert_users_check = $dbh>query($insert_site_configs); 103 104 // コミット 105 $dbh->commit(); 106 107} catch (PDOException $e) { 108 // ロールバック 109 $dbh->rollBack(); 110 echo 'DB接続エラー:' . $e->getMessage(); 111 die(); 112} catch (Throwable $e) { 113 echo "ロールバック"; 114 // ロールバック 115 $dbh->rollBack(); 116 echo '失敗:' . $e->getMessage(); 117 die(); 118} 119 120$dbh = null; 121 122?>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/05/11 08:50

回答依頼いただきましたが、既についた回答で進めることは可能かと思います。
guest

回答2

0

まずはデバッグとして
$dbh->commit();
の箇所を
$dbh->rollback();
にして、元に戻るかどうかチェックするところからです

投稿2020/05/11 06:56

yambejp

総合スコア116724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaito2414

2020/05/11 07:00

行ったところやはり $del = "DELETE FROM ".$table_name; $dbh->query($del); のみ通ってしまいますね。 DELETEはトランザクションに対応してないのでしょうか
yambejp

2020/05/11 07:10

いえ、DELETEは大丈夫なはずです。 categoriesテーブルの詳細な情報を提示ください
kaito2414

2020/05/11 07:12

CREATE TABLE `categories` ( `id` bigint(20) NOT NULL COMMENT 'カテゴリID', `site_id` bigint(20) NOT NULL COMMENT 'サイトID', `parent_id` bigint(20) DEFAULT NULL COMMENT '親カテゴリID', `name` varchar(100) DEFAULT NULL COMMENT 'カテゴリ名', `pass` varchar(50) DEFAULT NULL COMMENT '実ディレクトリ名', `sort` int(11) NOT NULL COMMENT 'ソート番号', `level` tinyint(4) DEFAULT NULL COMMENT 'カテゴリ階層(大:1 中:2)', `color` varchar(50) DEFAULT NULL COMMENT 'カテゴリカラー', `user_id` bigint(20) NOT NULL COMMENT '更新者', `created` datetime DEFAULT NULL COMMENT '作成日付', `modified` datetime DEFAULT NULL COMMENT '更新日付', `deleted` datetime DEFAULT NULL COMMENT '削除日付' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ALTER TABLE `categories` ADD PRIMARY KEY (`id`), ADD KEY `parent_id` (`parent_id`), ADD KEY `level` (`level`); ALTER TABLE `categories` MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'カテゴリID', AUTO_INCREMENT=24; COMMIT;
guest

0

ベストアンサー

MySQLでは、ALTER TABLEは強制的にトランザクション外となり、それ以前に行われていたトランザクションもすべてコミットしてしまいます(8.0のマニュアル)。

投稿2020/05/11 07:11

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaito2414

2020/05/11 07:24

ALTER TABLE文を削除しても $del = "TRUNCATE TABLE ".$table_name; $dbh->query($del); のみ通ってしまいますね
maisumakun

2020/05/11 07:29

TRUNCATE TABLEも同様に、トランザクションに含められない命令です。
kaito2414

2020/05/11 07:35

なるほど、、、では上書きをトランザクションで行うにはどの構文がふさわしいでしょうか? (テーブルにデータがない場合も含め)
sazi

2020/05/11 13:02

そもそもトランザクション制御の目的は何ですか? オートナンバーをリセットしているようですけど、オートナンバーもトランザクション制御はされませんよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問