क्या मैं 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

नहीं, आप नहीं कर सकते।

हालाँकि, आप ऐसा करने के लिए आसानी से एक ट्रिगर बना सकते हैं, जैसे:

पहले TR_GER_INsert_app_users बनाएं
  पहले से ही app_users पर सम्मिलित करें 
  हर एक के लिए
  SET new.api_key = uuid ();

2
मौजूदा पंक्तियों में UUIDs को आबाद करने के लिए @See stackoverflow.com/questions/6280789/…
सैम बार्नम

2
यह DEFAULT मान होने के समान नहीं है। यदि मूल्य NULL था तो कोई इस उत्तर को केवल कुंजी सेट करने के लिए कैसे बदलेगा?
टूलमेकरसेव

1
दुख की बात है कि MySQL के रूप में लंबे समय के लिए किया गया है, लेकिन आप एक ट्रिगर के बिना एक कॉलम के लिए एक डिफ़ॉल्ट UUID को लागू नहीं कर सकते। इसका कारण यह है कि 1980 की तकनीक में अंतर्निहित है जो जाहिरा तौर पर अभी भी MySQL आधार कोड में मौजूद है ("हम अच्छी चीजें नहीं कर सकते हैं" के लिए खोज): percona.com/blog/2013/04/08/…
रयानरॉड

1
@RodolVelasco uuid फ़ंक्शन अत्यधिक टक्कर प्रतिरोधी होने के लिए बनाया गया है। Md5 की तुलना में बहुत अधिक। जैसे ही आप md5 को uuid करते हैं, आपके पास id टकराने का खतरा अधिक होता है
Cruncher

2
SET new.api_key = COALESCE(new.api_key, uuid())मौजूदा मूल्यों को संरक्षित करने के लिए।
रयान

28

Mysql v8.0.13 के रूप में किसी फ़ील्ड के लिए डिफ़ॉल्ट मान के रूप में अभिव्यक्ति का उपयोग करना संभव है:

डिफॉल्ट क्लॉज में निर्दिष्ट डिफ़ॉल्ट मान शाब्दिक स्थिर या एक अभिव्यक्ति हो सकता है। एक अपवाद के साथ, कोष्ठक के भीतर अभिव्यक्ति डिफ़ॉल्ट मानों को संलग्न करें ताकि उन्हें शाब्दिक निरंतर डिफ़ॉल्ट मानों से अलग किया जा सके।

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

1
ध्यान दें कि उत्तर में पहले से लिंक किए गए डॉक्स के अनुसार: ... संग्रहीत कार्य और उपयोगकर्ता-परिभाषित फ़ंक्शन की अनुमति नहीं है । यानी, केवल वही फ़ंक्शन जिनका उपयोग डिफ़ॉल्ट अभिव्यक्तियों के रूप में किया जा सकता है, अंतर्निहित कार्य हैं।
अशरबार

1
मई 2020 तक यह सही उत्तर होना चाहिए। ट्रिगर्स का उपयोग करने वाले अन्य उत्तर अप्रचलित हैं।
जॉन स्टॉक

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 को डिफ़ॉल्ट के लिए स्थिरांक की आवश्यकता होती है। इस मुद्दे पर नीचे दिए गए लिंक में और अधिक विस्तार से चर्चा की गई थी। लेकिन एकमात्र जवाब शून्य की अनुमति देना और तालिका ट्रिगर जोड़ना है।

MySQL ने हाल ही में UUID को उनके DB पैकेज के हिस्से के रूप में स्वीकार किया है, और यह उतना अमीर नहीं है जितना हम चाहते हैं।

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


1
मुझे यह जोड़ना चाहिए कि NULL और ट्रिगर्स पर निर्भर होने की अनुमति देना काम कर सकता है, लेकिन अधिकांश डेवलपर्स इसे बहुत हैक-वाई समाधान मानेंगे। मैं व्यक्तिगत रूप से इसकी अनुशंसा नहीं करूंगा, लेकिन प्रत्येक अपने स्वयं के लिए।
ट्रैविसो

6

मेरा मानना ​​है कि आप ऐसा नहीं कर सकते :

डिफ़ॉल्ट मान एक स्थिर होना चाहिए; यह एक समारोह या एक अभिव्यक्ति नहीं हो सकता है


सच नहीं है, आप getdate ()
amr ओसामा

6
@amrosama - नहीं, आप नहीं कर सकते। getdate()एक MySQL फ़ंक्शन भी नहीं है। उत्तर में लिंक एकमात्र अपवाद बताता है: «आप CURRENT_TIMESTAMP को किसी TIMESTAMP स्थान» के लिए डिफ़ॉल्ट के रूप में निर्दिष्ट कर सकते हैं
अल्वारो गोंजालेज

1
CURRENT_TIMESTAMP केवल "फ़ंक्शन" है जिसका उपयोग डिफ़ॉल्ट मान के रूप में किया जा सकता है। बाकी सब कुछ एक स्थिर (दुर्भाग्य से) होना चाहिए।
ट्रॉय मोरहाउस

3
तकनीकी रूप से मैं कहूंगा कि AUTO_INCREMENT को एक डिफ़ॉल्ट मान को गतिशील रूप से सेट करने के लिए "फ़ंक्शन" के रूप में भी देखा जा सकता है।
रिकेलस

1

ध्यान दें कि MySQL के UUID()रिटर्न CHAR(36), और UUIDs को पाठ के रूप में संग्रहीत करना (जैसा कि अन्य उत्तरों में दिखाया गया है) स्पष्ट रूप से अक्षम है। इसके बजाय, स्तंभ होना चाहिए 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-टेबल /


0

मुझे यकीन नहीं है कि यदि उपरोक्त उत्तर पुराने संस्करण के लिए हैं, लेकिन मैंने कहीं न कहीं देखा है कि आप इसे अनहैक्स () फ़ंक्शन का उपयोग करके कर सकते हैं। मैने इसे आजमाया और इसने कार्य किया। (मारिया डीबी संस्करण १०.२)

तुम कर सकते हो

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

और यह काम करता है। Uuid देखने के लिए बस हेक्स (column_name) करें।


0

मारियाडीबी में 10.2.1 संस्करण से शुरू हो सकता है। इसका प्रलेखन देखें ।

CREATE TABLE test ( uuid BINARY(16) PRIMARY KEY DEFAULT unhex(replace(uuid(),'-','')) );
INSERT INTO test () VALUES ();
SELECT * FROM test;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.