MySQL 4.0 में निर्मित और अंतिम अपडेट किए गए दोनों टाइमस्टैम्प कॉलम दोनों


127

मेरे पास निम्न तालिका स्कीमा है;

CREATE TABLE `db1`.`sms_queue` (
  `Id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `Message` VARCHAR(160) NOT NULL DEFAULT 'Unknown Message Error',
  `CurrentState` VARCHAR(10) NOT NULL DEFAULT 'None',
  `Phone` VARCHAR(14) DEFAULT NULL,
  `Created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `LastUpdated` TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  `TriesLeft` tinyint NOT NULL DEFAULT 3,
  PRIMARY KEY (`Id`)
)
ENGINE = InnoDB;

यह निम्न त्रुटि के साथ विफल रहता है:

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause.

मेरा सवाल यह है कि क्या मैं उन दोनों क्षेत्रों में हो सकता हूं? या क्या मुझे प्रत्येक लेनदेन के दौरान मैन्युअल रूप से लास्टअप फ़ील्ड सेट करना होगा?


अरे, @Xenph यान, क्या आप "गलत" उत्तर को वर्तमान गलत एक से सही एक में बदलना चाहेंगे? यह स्वीकार किया गया, गलत जवाब ने मुझे लगभग 15 मिनट गंवा दिए और यह पता लगाने की कोशिश की कि क्या हो रहा है ...
ब्रूनो रीस

1
@BrunoReis किया, लेने के लिए धन्यवाद।
एक्सनफ यान

जवाबों:


128

से MySQL 5.5 प्रलेखन :

किसी तालिका में एक टाइमस्टैम्प स्तंभ में स्तंभ को प्रारंभ करने के लिए डिफ़ॉल्ट मान के रूप में वर्तमान टाइमस्टैम्प हो सकता है, ऑटो-अपडेट मान के रूप में, या दोनों। वर्तमान टाइमस्टैम्प का एक कॉलम के लिए डिफ़ॉल्ट मान होना और किसी अन्य कॉलम के लिए ऑटो-अपडेट मूल्य होना संभव नहीं है।

MySQL में परिवर्तन 5.6.5 :

पहले, प्रति टेबल पर अधिकांश TIMESTAMP कॉलम वर्तमान दिनांक और समय के अनुसार स्वचालित रूप से प्रारंभ या अद्यतन किया जा सकता था। यह प्रतिबंध हटा लिया गया है। किसी भी TIMESTAMP स्तंभ की परिभाषा में DEFAULT CURRENT_TIMESTAMP और ON UPDATE CURRENT_TIMESTAMP क्लॉस का कोई संयोजन हो सकता है। इसके अलावा, अब इन खंडों को DATETIME स्तंभ परिभाषाओं के साथ उपयोग किया जा सकता है। अधिक जानकारी के लिए, TIMESTAMP और DATETIME के ​​लिए स्वचालित प्रारंभ और अद्यतन देखें।


यह बदल गया है (कम से कम MySQL 5.0 में)। प्रलेखन देखें: dev.mysql.com/doc/refman/5.0/en/timestamp.html
सिमोनसिमिटी

काउंटरिंग @SimonSimCity: 5.0 के लिए डॉक्स ऊपर के रूप में सटीक एक ही बात कहते हैं।
डेविमरॉन

5
@RobertGamble मुझे लगता है कि अधिक दिलचस्प सवाल यह है कि वे ऐसा नहीं करेंगे, क्योंकि उन्होंने ऐसा तरीका नहीं दिया है जो आमतौर पर अनुरोधित / आवश्यक कार्यक्षमता के लिए है।
रे

22
यह MySQL के हिस्से पर थोड़ा मनमाना लगता है। क्या कोई समझा सकता है कि ऐसा क्यों है?
विनम्र_कोडर

12
वास्तव में वास्तव में पुरानी टिप्पणी, लेकिन, यह अंततः बदल गया था: Changes in MySQL 5.6.5 (2012-04-10, Milestone 8) Previously, at most one TIMESTAMP column per table could be automatically initialized or updated to the current date and time. This restriction has been lifted. Any TIMESTAMP column definition can have any combination of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses. In addition, these clauses now can be used with DATETIME column definitions. For more information, see Automatic Initialization and Updating for TIMESTAMP and DATETIME.
मौरिसियो वर्गास

83

दोनों टाइमस्टैंप होने के लिए एक चाल है, लेकिन थोड़ी सी सीमा के साथ।

आप एक तालिका में केवल एक परिभाषा का उपयोग कर सकते हैं। दोनों टाइमस्टैम्प कॉलम बनाएं जैसे:

create table test_table( 
  id integer not null auto_increment primary key, 
  stamp_created timestamp default '0000-00-00 00:00:00', 
  stamp_updated timestamp default now() on update now() 
); 

ध्यान दें कि इस nullदौरान दोनों कॉलम में प्रवेश करना आवश्यक है insert:

mysql> insert into test_table(stamp_created, stamp_updated) values(null, null); 
Query OK, 1 row affected (0.06 sec)

mysql> select * from test_table; 
+----+---------------------+---------------------+ 
| id | stamp_created       | stamp_updated       |
+----+---------------------+---------------------+
|  2 | 2009-04-30 09:44:35 | 2009-04-30 09:44:35 |
+----+---------------------+---------------------+
2 rows in set (0.00 sec)  

mysql> update test_table set id = 3 where id = 2; 
Query OK, 1 row affected (0.05 sec) Rows matched: 1  Changed: 1  Warnings: 0  

mysql> select * from test_table;
+----+---------------------+---------------------+
| id | stamp_created       | stamp_updated       | 
+----+---------------------+---------------------+ 
|  3 | 2009-04-30 09:44:35 | 2009-04-30 09:46:59 | 
+----+---------------------+---------------------+ 
2 rows in set (0.00 sec)  

यहाँ MySQL-Documentation का एक लिंक दिया गया है जो उस फ़ंक्शन का वर्णन करता है: dev.mysql.com/doc/refman/5.0/en/timestamp.html
SimonSimCity

6
पहला कोड बॉक्स, जब मैन्युअल रूप से दर्ज किया गया तो मेरे लिए पूरी तरह से काम किया। धन्यवाद! काश मेरे पास इस उत्तर को उभारने के लिए पर्याप्त 'कर्म' होते क्योंकि यह मेरी बेकन को बचा लेता। mmmmm ने बेकन को बचाया।
अमातुस्को

आपको यह सुनिश्चित करने की आवश्यकता है कि stamp_created यह भी पूरी तरह से सेट नहीं है। MySQL स्वचालित रूप से NULL को वर्तमान टाइमस्टैम्प से बदल देगा।
वैलेंटाइन देस्पा

आप stamp_createdफ़ील्ड को stamp_created timestamp default now()'ZERO' मान का उपयोग करने के बजाय क्यों नहीं बनाते हैं ?
सेबेस्टियन शोले

28

आप उन दोनों को ले सकते हैं, बस बनाए गए फ़ील्ड पर "CURRENT_TIMESTAMP" ध्वज को उतारें। जब भी आप तालिका में एक नया रिकॉर्ड बनाते हैं, तो मूल्य के लिए "अभी ()" का उपयोग करें।

या।

इसके विपरीत, 'ON UPDATE CURRENT_TIMESTAMP' ध्वज को हटा दें और उस फ़ील्ड के लिए Now () भेजें। इस तरह वास्तव में अधिक समझ में आता है।


2
क्या यह एकमात्र तरीका है? मैं डेटाबेस को विस्तार से देख नहीं सकता?
एक्सनफ यान

2
MySql मैनुअल के अनुसार, CURRENT_TIMESTAMP अभी () के लिए एक पर्याय है, इसलिए मुझे नहीं लगता कि यह काम करेगा।
tvanfosson

मुझे यकीन है कि आप कर सकते हैं, यह सिर्फ इतना है कि CURRENT_TIMESTAMP केवल एक फ़ील्ड के लिए आरक्षित ध्वज है। किसी भी तरह से, यदि आपके पास उस झंडे को वहां रखा गया है, तो चाहे आप उस क्षेत्र के लिए क्या मूल्य रखते हैं जब आप एक रिकॉर्ड जोड़ते हैं, तो यह हमेशा वर्तमान टाइमस्टैम्प होगा, इसलिए नाम।
स्टीफन वाल्चर

1
@tvanfosson: क्वेरी में 'अब ()' का उपयोग करने से डेटाबेस का वर्तमान समय गुजरता है। वह मूल्य वास्तव में भाषा, इंजन और शायद सौ अन्य चीजों पर निर्भर करता है जो मैं नहीं जानता। जिस झंडे का मैं जिक्र कर रहा था, वह इसे सेट कर रहा था ताकि जब कोई रिकॉर्ड बनाया जाए तो उस फील्ड में समय जोड़ा जाए।
स्टीफन वाल्चर

2
मैं इन्सर्ट नाउ () तरीके से गया था, क्योंकि ज्यादातर कोड इन तालिकाओं को छू सकते थे और मुझे विश्वास नहीं होता कि लोग उन्हें सही तरीके से अपडेट कर पाएंगे। :)
एक्सएफ़एन यान

26

यदि आप टाइमस्टैम्प के अपडेट को MySQL करने का निर्णय लेते हैं, तो आप सम्मिलित पर फ़ील्ड को अपडेट करने के लिए ट्रिगर सेट कर सकते हैं।

CREATE TRIGGER <trigger_name> BEFORE INSERT ON <table_name> FOR EACH ROW SET NEW.<timestamp_field> = CURRENT_TIMESTAMP;

MySQL संदर्भ: http://dev.mysql.com/doc/refman/5.0/en/triggers.html


अच्छा यह था कि मैं क्या देख रहा था। मैं अब क्वेरी में जोड़े गए लोगों पर भरोसा नहीं करना चाहता!
बॉट

वास्तव में डालने के बाद ऐसा करना बेहतर होगा, और नया सेट करें। <timestamp_field> = new। <timestamp_field जिसे वास्तव में डिफ़ॉल्ट current_timestamp मिला है> इस तरह से दोनों फ़ील्ड
समरूप

@KacieHouser ट्रिगर के बाद नई पंक्ति को अपडेट करने की अनुमति नहीं है
थॉमस

23

यह है कि आप कैसे स्वचालित और लचीला createDate / lastModified फ़ील्ड ट्रिगर का उपयोग कर सकते हैं:

पहले उन्हें इस तरह परिभाषित करें:

CREATE TABLE `entity` (
  `entityid` int(11) NOT NULL AUTO_INCREMENT,
  `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `lastModified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `name` varchar(255) DEFAULT NULL,
  `comment` text,
  PRIMARY KEY (`entityid`),
)

फिर इन ट्रिगर्स को जोड़ें:

DELIMITER ;;
CREATE trigger entityinsert BEFORE INSERT ON entity FOR EACH ROW BEGIN SET NEW.createDate=IF(ISNULL(NEW.createDate) OR NEW.createDate='0000-00-00 00:00:00', CURRENT_TIMESTAMP, IF(NEW.createDate<CURRENT_TIMESTAMP, NEW.createDate, CURRENT_TIMESTAMP));SET NEW.lastModified=NEW.createDate; END;;
DELIMITER ;
CREATE trigger entityupdate BEFORE UPDATE ON entity FOR EACH ROW SET NEW.lastModified=IF(NEW.lastModified<OLD.lastModified, OLD.lastModified, CURRENT_TIMESTAMP);
  • यदि आप createDate या lastModified निर्दिष्ट किए बिना सम्मिलित करते हैं, तो वे समान होंगे और वर्तमान टाइमस्टैम्प पर सेट होंगे।
  • यदि आप createDate या lastModified निर्दिष्ट किए बिना उन्हें अपडेट करते हैं, तो LastModified वर्तमान टाइमस्टैम्प पर सेट हो जाएगा।

लेकिन यहाँ अच्छा हिस्सा है:

  • यदि आप सम्मिलित करते हैं , तो आप वर्तमान टाइमस्टैम्प की तुलना में पुराने से एक CreateDate को निर्दिष्ट कर सकते हैं , जो पुराने समय से आयात को अच्छी तरह से काम करने की अनुमति देता है (lastModified createDate के बराबर होगा)।
  • यदि आप अपडेट करते हैं , तो आप पिछले मान ('0000-00-00 00:00:00' अच्छी तरह से काम करता है) की तुलना में एक पुराने को निर्दिष्ट कर सकते हैं , यदि आप कॉस्मेटिक बदलाव कर रहे हैं तो एक प्रविष्टि को अपडेट करने की अनुमति देता है (एक टिप्पणी में एक टाइपो को ठीक करना) ) और आप पुरानी अंतिम तिथि को रखना चाहते हैं । यह अंतिम बार संशोधित तिथि को संशोधित नहीं करेगा।

21

MySQL 5.6 के रूप में इसकी आसान-दया ... इसे आज़माएं:

create table tweet ( 
    id integer not null auto_increment primary key, 
    stamp_created timestamp default now(), 
    stamp_updated timestamp default now() on update now(),
    message varchar(163)
)

शायद महान समाधान मैं क्या बनाने और बिना अद्यतन समय मुद्दा ट्रिगर तलाश कर रहा हूँ
matinict

मैं विश्वास नहीं कर सकता कि इस छोटे से उपद्रव को हल करने में इतना समय लगा। मुझे एहसास भी नहीं हुआ कि उन्होंने इसे ठीक कर लिया है और यह 2018 है ... धन्यवाद।
hsanders

4

ऐसा प्रतीत होता है कि यह समस्या MySQL 5.6 में हल हो गई है। मैंने MySQL 5.5 तक इस पर ध्यान दिया है; यहाँ एक उदाहरण कोड है:

DROP TABLE IF EXISTS `provider_org_group` ;
CREATE TABLE IF NOT EXISTS `provider_org_group` (
  `id` INT NOT NULL,
  `name` VARCHAR(100) NOT NULL,
  `type` VARCHAR(100) NULL,
  `inserted` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `insert_src_ver_id` INT NULL,
  `updated` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
  `update_src_ver_id` INT NULL,
  `version` INT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC),
  UNIQUE INDEX `name_UNIQUE` (`name` ASC))
ENGINE = InnoDB;

MySQL 5.5 पर इसे चलाने से यह मिलता है:

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

इसे MySQL 5.6 पर चलाना

0 row(s) affected   0.093 sec


2

Mysql 5.7.21 के लिए मैं निम्नलिखित का उपयोग करता हूं और ठीक काम करता हूं:

बनाएँ तालिका Posts( modified_atअद्यतन CURRENT_TIMESTAMP पर पूर्ण डायवर्ट CURRENT_TIMESTAMP ( टाइमस्टैम्प नॉट नॉट created_atडीएफ़ल्ट CULLRENT_TIMESTAMP)


1

मुझे लगता है कि यह Stamp_created और Stamp_updated के लिए बेहतर क्वेरी है

CREATE TABLE test_table( 
    id integer not null auto_increment primary key, 
    stamp_created TIMESTAMP DEFAULT now(), 
    stamp_updated TIMESTAMP DEFAULT '0000-00-00 00:00:00' ON UPDATE now() 
); 

क्योंकि जब रिकॉर्ड बनाया जाता है, stamp_createdतो उसे भरना चाहिए now()और उसके द्वारा भरना stamp_updatedचाहिए'0000-00-00 00:00:00'


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.