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

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

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

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

MariaDB

MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。

Q&A

解決済

2回答

1432閲覧

MySQLで「日本語でも英語でも5文字」に制限したい

nikuatsu

総合スコア177

MySQL

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

MariaDB

MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。

0グッド

1クリップ

投稿2022/02/07 05:39

前提・実現したいこと

データベースで「日本語でも英語でも5文字まで」という投稿機能を実装したく思い、該当のソースコードにあるようなVARCHAR(5)を指定しました。

そこでMySQL側でVARCHARの指定を超えたらエラーになる機能を実装したいです。

発生している問題

以下リンクによれば、文字数を超えたら「> エラーになるのがSQL標準」とのこと。しかし実際にはINSETできてしまい、エラーになりません。

文字数制限のあるVARCHARへのINSERT/UPDATEをエラーでなく切り詰めに

該当のソースコード

問題(エラーにならないこと)が生じるCREATE、INSERTです。

SQL

1CREATE TABLE IF NOT EXISTS my_test ( 2 ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT 3 ,name VARCHAR(5) # 5文字までに制限 4 ,PRIMARY KEY (ID) 5); 6 7INSERT INTO my_test (name) VALUES ('あいうえおか'); # 5文字を超えたINSERTを実行

上記INSERTの結果がこちらの画像で、あいうえおかのうちあいうえおがINSERTされてしまい、特にエラーが生じません。

イメージ説明

試したこと

PHPで以下の検証を挟みました。mb_strlenを用いて、5文字を超えたnameのINSERTを防ぐ意図です。

PHP

1$name = filter_input( INPUT_POST, 'name' ); 2if ( mb_strlen( $name ) > 5 ) { 3 $result = ['status' => 'error', 'mes' => 'nameは5文字までです' ]; 4 echo( json_encode( $result ) ); 5} else { 6 $sql = "INSERT INTO my_test (name) values (%s);"; // 5文字を超えたnameのINSERTを防ぐ 7 /* 以下略 */

しかしMySQL側での制限が出来た方が安心に感じます。
どうしたらエラーが出るようになりますでしょうか?

補足情報(FW/ツールのバージョンなど)

MySQL は 5.7 を使用しています。
宜しくお願い致します。

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

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

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

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

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

guest

回答2

0

ベストアンサー

MySQL5.7.6以降であれば生成列がつかえるので、無理やり外部キー制約と合わせればできないことは無いと思います。
(効率的かと言われると怪しいですが・・・)

SQL

1/* 制約用のマスターテーブルを用意 */ 2create table chk(num int primary key); 3insert into chk values(0),(1),(2),(3),(4),(5); 4 5/* 5文字までならあえて+1して6文字までの制限とする */ 6create table tbl(id int primary key,val varchar(6),chk int as (char_length(val)), 7foreign key(chk) references chk(num) on delete cascade); 8 9insert ignore into tbl(id,val) values 10(1,'abc'), 11(2,'abcde'), 12(3,'abcdef'), 13(4,'abcdefghijk'), 14(5,'あいう'), 15(6,'あいうえお'), 16(7,'あいうえおか');

※6文字以上の文字が投入されるとchkカラムが6になり、
外部キー制約でエラーとなってinsertが取り消されます

※一部調整

投稿2022/02/07 06:35

編集2022/02/07 06:42
yambejp

総合スコア114585

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

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

nikuatsu

2022/02/07 08:45

ありがとうございます。これだけ手間が必要になるということは、質問のようなエラーを出したいというケースはあまり多くないのでしょうか?(意図せず丸め込まれると困ると思うのですが…)
yambejp

2022/02/07 09:19 編集

最新のMySQLではCHECK制約機能が追加されているようです > 意図せず丸め込まれると困る 無駄な負荷をかけるくらいなら許容範囲でデータを投入するほうが良いような気もしますが プロシージャなどでも事前チェックは可能ですので、 あえてDBの入力制限を利用する必要はないと思います
nikuatsu

2022/02/07 11:36

なるほど。アドバイスありがとうございます。
guest

0

エラーになるのがSQL標準

MySQLはデフォルトで、標準に従わない形で動作しています。それを変えるには、SQLモードの指定が必要です。

投稿2022/02/07 06:03

maisumakun

総合スコア145123

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

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

nikuatsu

2022/02/07 08:45

ありがとうございます。デフォルトで標準に従わないとはwリンク先勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問