MySqlのデフォルト値に関数を使用できますか?


93

私はこのようなことをしたいです:


create table app_users
(
    app_user_id smallint(6) not null auto_increment primary key,
    api_key     char(36) not null default uuid()
);

しかし、これはエラーになります、mysqlのデフォルト値の関数を呼び出す方法はありますか?

ありがとう。

回答:


129

いいえ、できません。

ただし、次のようなトリガーを簡単に作成できます。

CREATE TRIGGER before_insert_app_users
  BEFORE INSERT ON app_users 
  各列
  SET new.api_key = uuid();

2
既存の行にUUIDを入力する方法については、@ stackoverflow.com / questions / 6280789 /を参照してください。
Sam Barnum 2013年

2
これは、DEFAULT値を持つこととはまったく異なります。値がNULLの場合にのみキーを設定するようにこの回答をどのように変更しますか?
ToolmakerSteve 2015

1
MySQLは長い間存在していますが、トリガーなしで列のデフォルトUUIDを実装することはできません。この理由は明らかにまだMySQLのベースコード(「私たちはすてきなものを持つことができません」で検索)に存在することを1980年の技術に埋め込まれpercona.com/blog/2013/04/08/...
RyanNerd

1
@RodolVelasco uuid関数は、非常に衝突に強いように構築されています。md5よりもはるかに。uuidをmd5するとすぐに、ID衝突のリスクが高くなります
Cruncher

2
SET new.api_key = COALESCE(new.api_key, uuid())既存の値を保持します。
ライアン

29

のとしてのMySQL v8.0.13フィールドのデフォルト値として式を使用することが可能です。

DEFAULT句で指定するデフォルト値は、リテラル定数または式にすることができます。1つの例外を除いて、式のデフォルト値を括弧で囲んで、リテラル定数のデフォルト値と区別します。

CREATE TABLE t1 (
  uuid_field     VARCHAR(32) DEFAULT (uuid()),
  binary_uuid    BINARY(16)  DEFAULT (UUID_TO_BIN(UUID()))
);

1
回答で既にリンクされているドキュメントに従って:...ストアド関数、およびユーザー定義関数は許可されないことに注意してください。つまり、デフォルトの式として使用できる関数は組み込み関数だけです。
アシャーバー

2
2020年5月の時点で、これが正解になるはずです。トリガーを使用する他の回答は廃止されました。
ジョン株式

20

すでに述べたようにできません。

この動作をシミュレートする場合は、次のようにトリガーを使用できます。

CREATE TRIGGER before_insert_app_users
BEFORE INSERT ON app_users
FOR EACH ROW
  IF new.uuid IS NULL
  THEN
    SET new.uuid = uuid();
  END IF;

次のように、以前に存在していた行を更新する必要があります。

UPDATE app_users SET uuid = (SELECT uuid());

8

残念ながら、MySQL 5ではデフォルトの定数が必要です。この問題については、以下のリンクで詳細に説明されています。しかし、唯一の答えはnullを許可し、テーブルトリガーを追加することです。

MySQLは最近、UUIDをDBパッケージの一部として受け入れただけであり、希望するほど機能が豊富ではありません。

http://www.phpbuilder.com/board/showthread.php?t=10349169


1
NULLを許可し、トリガーに依存することは機能する可能性があることを追加する必要がありますが、ほとんどの開発者はそれを非常にハックなソリューションと見なします。私は個人的にはお勧めしませんが、それぞれに推奨します。
TravisO

6

あなたはできない思います

デフォルト値は定数でなければなりません。関数や式にすることはできません


真実ではありません。getdate()を使用できます
amr osama

6
@amrosama-いいえ、できません。getdate()MySQL関数でもありません。回答のリンクは、唯一の例外を説明しています:«TIMESTAMP列のデフォルトとしてCURRENT_TIMESTAMPを指定できます»
アルバロゴンサレス

1
CURRENT_TIMESTAMPは、デフォルト値として使用できる唯一の「関数」です。それ以外はすべて定数でなければなりません(残念ながら)。
Troy Morehouse

3
技術的には、AUTO_INCREMENTは、デフォルト値を動的に設定する「関数」と見なすこともできます。
Rikaelus 2017年

1

注MySQLのことUUID()に戻りCHAR(36)、テキストが(他の回答のように)明らかに非効率的であるとしてUUIDを保存します。代わりに、列はである必要がありBINARY(16)UUID_TO_BIN()データを挿入するときやデータをBIN_TO_UUID()読み取るときに使用できます。

CREATE TABLE app_users
(
    app_user_id SMALLINT(6) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    api_key     BINARY(16)
);

CREATE TRIGGER before_insert_app_users
BEFORE INSERT ON app_users
FOR EACH ROW
  IF new.api_key IS NULL
  THEN
    SET new.api_key = UUID_TO_BIN(UUID());
  END IF;

MySQLはこれがUUIDであることを実際には認識していないため、バイナリとして保存されている問題のトラブルシューティングが難しい場合があります。この記事では、スペースを占有したり、バイナリバージョンとテキストバージョンを別々に同期したりすることを心配することなく、必要に応じてUUIDをテキストに変換する生成列を作成する方法について説明します。https//mysqlserverteam.com/storing-uuid-values-in -mysql-tables /


0

上記の答えが古いバージョンのものかどうかはわかりませんが、unhex()関数を使用してこれを実行できることがどこかで見られました。私はそれを試してみましたが、うまくいきました。(マリアDBバージョン10.2)

できるよ

.... column_name binary(16) not null default unhex(replace(uuid(),'-',''))   

そしてそれは動作します。UUIDを表示するには、hex(column_name)を実行します。


0

MariaDBでは、バージョン10.2.1以降で可能です。ドキュメントを参照してください。

CREATE TABLE test ( uuid BINARY(16) PRIMARY KEY DEFAULT unhex(replace(uuid(),'-','')) );
INSERT INTO test () VALUES ();
SELECT * FROM test;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.