型の制限以上のデータを格納しようとすると、制限値で切り捨てられます(仕様として理解してます)。
例:tinyIntに200→127
varchar(20)に100文字→20byte目で切り捨て
他言語からSQLを流す前に値チェックなどをすれば良いのですが、SQLを直に流す際にもなんとかしたいなと…。
切り捨ての振る舞いが発生する時点で、エラーとして処理→DB rollbackしたいのですが、何か設定方法などありますでしょうか?
或いは切捨てが発生するかチェックできるSQL文はありますでしょうか?
環境は
OS FreeBSD
Mysql 4.0.27
権限はユーザ権限(非root)です。
文字コードの問題がありますが、MySQL 5.0.2以降にバージョンアップできないでしょうか?
MySQL 5.0.2以降で、標準のインストール時、切捨てでなくエラーになる設定に変わっています。
これは、My.iniに、以下の設定が標準値で入っているためです。
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
STRICT_TRANS_TABLESが、この仕様変更の動作をする指定です。
MySQL AB :: MySQL 5.0 Reference Manual :: 5.2.6 SQL Modes
また、MySQL 5.0から、情報スキーマが実装され、SQLで表の定義情報を得られるようになっています。
MySQL AB :: MySQL 5.0 Reference Manual :: 20 The INFORMATION_SCHEMA Database
MySQL AB :: MySQL 5.1 リファレンスマニュアル :: 21 INFORMATION_SCHEMA データベース
MySQL 4.0系で「表の定義情報と比較して切り捨てを行なう」というのは、表の個数や列の個数が相当に少なく、変更も殆どないのでなければ、実用に耐えないと思います。
MySQL AB :: MySQL 4.1 リファレンスマニュアル :: 6.4.3 INSERT 構文
INSERT であれば、実行後に mysql_info() 関数で情報を得ることができます。
ただし件数程度で実際に詳細なデータは得られないようです。
INSERT ... SELECT または INSERT ... VALUES ステートメントを複数の値のリスト付きで使用する場合は、C API 関数 mysql_info() を使用してクエリに関する情報を取得することができます。
確認いたしました。
うーむ、今回は必要なさそうな情報です…。
確かにSQLを流す段階でなんとかしたいですね。
---------------------------------------------------
あまりよくない方法だと思いますけど、
INSERTした後で、
SELECTして両者を比較して、一致しなかったら
ロールバック
主キーは、型の制限以上のデータを入れないことが前提に
なりますが・・・。
--------------------------------------------------
トリガとか使うと楽そうですが、5.0からなんですよね。
なるほど、挿入後のデータをコミット前にその場で確認は基本ですね。
すいません、こちら側の環境情報開示不足でした
レンタルサーバ環境で、shログインは可能ですが非root権限です。
mysql用のサーバは別サーバで
レンタルサーバ環境に一度shでログインして、
mysql -h hogehoge.hoge.jp -u user -p
で接続しています。
外部から繋ぐときはPortForwarderなどを使ってます。
mysql用のサーバへのログイン権限はありません。
Gccなど各種コンパイル環境はありますので、頑張れば サーバのユーザ領域に別途MySQL 5.0をインストールできるかも知れませんが、サーバ容量的・技術的に若干難がある状態です。