Как правильно вставить время по умолчанию? [Дубликат]

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

779
задан Moppo 12 July 2015 в 19:15
поделиться

24 ответа

ВАЖНОЕ ИЗМЕНЕНИЕ: теперь это можно достичь с помощью полей DATETIME, начиная с MySQL 5.6.5, взглянуть на другой пост ниже ...

Предыдущие версии могут Не делайте этого с DATETIME ...

Но вы можете сделать это с помощью TIMESTAMP:

mysql> create table test (str varchar(32), ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)

mysql> desc test;
+-------+-------------+------+-----+-------------------+-------+
| Field | Type        | Null | Key | Default           | Extra |
+-------+-------------+------+-----+-------------------+-------+
| str   | varchar(32) | YES  |     | NULL              |       | 
| ts    | timestamp   | NO   |     | CURRENT_TIMESTAMP |       | 
+-------+-------------+------+-----+-------------------+-------+
2 rows in set (0.00 sec)

mysql> insert into test (str) values ("demo");
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+------+---------------------+
| str  | ts                  |
+------+---------------------+
| demo | 2008-10-03 22:59:52 | 
+------+---------------------+
1 row in set (0.00 sec)

mysql>

** CAVEAT: Если вы по умолчанию задаете столбец с CURRENT_TIMESTAMP ON, вы необходимо ВСЕГДА указать значение для этого столбца, или значение автоматически перезапустится до «now ()» при обновлении. Это означает, что если вы не хотите, чтобы значение изменялось, ваш оператор UPDATE должен содержать «[имя вашего столбца] = [ваше имя столбца]» (или какое-то другое значение), или значение станет «now ()». Странно, но верно. Надеюсь, это поможет. Я использую 5.5.56-MariaDB **

754
ответ дан Community 19 August 2018 в 00:29
поделиться
  • 1
    важно отметить, что datetime имеет диапазон 1000-9999, но диапазон для метки времени - только 1970-2038 . это может быть проблемой, если ваша система должна хранить даты рождения, или вам нужно обработать что-то вроде плана платежей за 30-летнюю ипотеку. dev.mysql.com/doc/refman/5.0/en/datetime.html – Kip 27 September 2011 в 18:01
  • 2
    +1 для краткости вашего первого предложения. Мне нравятся такие ответы. Если мне нужен подробный фон, который тоже доступен. – John Zumbrum 17 August 2012 в 04:53
  • 3
    Будьте осторожны с отметкой времени, когда она автоматически обновляется магически ... см. Следующий ответ stackoverflow.com/a/1483959/233906 – Cerber 27 October 2012 в 13:31
  • 4
    Это возможно из версии 5.6.5, см. Ниже ответ Густава (я понимаю, что ваш ответ был опубликован, когда MySQL еще 5,0!) – Ring Ø 3 March 2013 в 15:57
  • 5
    @Kip, Hi, возможно ли иметь значение по умолчанию для столбца DATE ? (а не столбец datetime). – Sajib Acharya 3 March 2016 в 22:18
  • 6
    – Fabio Napodano 20 May 2016 в 08:39

Я смог решить это, используя этот оператор alter в моей таблице, который имел два поля datetime.

ALTER TABLE `test_table`
  CHANGE COLUMN `created_dt` `created_dt` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
  CHANGE COLUMN `updated_dt` `updated_dt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

Это работает так, как вы ожидали, что функция now () будет работать. Вставка нулей или игнорирование полей created_dt и updated_dt приводит к отличному значению метки времени в обоих полях. Любое обновление строки изменяет update_dt. Если вы вставляете записи через браузер запросов MySQL, вам нужен еще один шаг - триггер для обработки created_dt с новой меткой времени.

CREATE TRIGGER trig_test_table_insert BEFORE INSERT ON `test_table`
    FOR EACH ROW SET NEW.created_dt = NOW();

Триггер может быть любым, что вы хотите. Мне просто нравится соглашение об именах [ аккуратный] _ [my_table_name] _ [вставить]

22
ответ дан 2 revs, 2 users 74%user188217 19 August 2018 в 00:29
поделиться
  • 1
    Я хотел сказать: если вы вставляете записи через браузер запросов MySQL вручную через сетку без инструкции insert (), необходим триггер. Если вы всегда используете инструкцию insert, триггер полностью не нужен. – user 12 October 2009 в 06:07
  • 2
    Упс! Я имел в виду, что триггер (имя) может быть тем, чем вы хотите, потому что имя триггера вообще не влияет на функциональность. Большинство людей это узнают, но некоторые люди, не знакомые с MySQL, могут не знать ... – user 12 October 2009 в 06:18
  • 3
    Yikes, извините за отсутствие перерывов в линии. Используйте полуколоны, чтобы отметить конец каждой строки. – user 12 October 2009 в 06:27
  • 4
    Это будет работать в качестве обходного пути для Mysql 5.5. благодаря – Aakash 18 May 2018 в 14:06

Для всех тех, кто потерял сердце, пытаясь установить значение DATETIME по умолчанию в MySQL, я точно знаю, как вы себя чувствуете. Итак, вот что:

ALTER TABLE  `table_name` CHANGE `column_name` DATETIME NOT NULL DEFAULT 0

Тщательно наблюдайте, что я не добавил одиночных кавычек / двойных кавычек вокруг 0 ​​

Я буквально прыгаю после решения этой проблемы: D

13
ответ дан Augiwan 19 August 2018 в 00:29
поделиться
  • 1
    Он не вставляет не текущее время. Он будет вставлять '0000-00-00 00:00:00'. – Pit Digger 23 August 2011 в 16:27
  • 2
    Я не сказал, что он устанавливает текущее время. Многие ppl пытались установить нулевое значение по умолчанию, но оно просто не работает. Нам нужно исключить кавычки. Поскольку этот вывод вызвал много времени и разочарований, я подумал поделиться им с сообществом. Такие люди, как вы, несут ответственность за то, что пользователи теряют интерес к обмену полезной информацией с другими людьми. Я серьезно не вижу причин, чтобы получить -1! Без разницы. – Augiwan 24 August 2011 в 14:41
  • 3
    То же самое можно достичь с помощью DATETIME NOT NULL. – Brendan Byrd 17 February 2014 в 20:25
  • 4
    В примере sql-команды есть еще один символ, который я не могу редактировать, поскольку это только односимвольное редактирование. – quapka 24 May 2016 в 09:26

MySQL ( до версии 5.6.5 ) не позволяет использовать функции для значений по умолчанию DateTime. TIMESTAMP не подходит из-за его нечетного поведения и не рекомендуется использовать в качестве входных данных. (См. Тип данных MySQL по умолчанию .)

Тем не менее, вы можете выполнить этот , создав триггер .

У меня есть таблицу с полем DateCreated типа DateTime. Я создал триггер в этой таблице «Before Insert» и «SET NEW.DateCreated=NOW()», и он отлично работает.

Надеюсь, это поможет кому-то.

136
ответ дан Bradley Slavik 19 August 2018 в 00:29
поделиться
  • 1
    CREATE TRIGGER trigger_foo_SetCreatedAt ПЕРЕД ВСТАВКОЙ НА foo ДЛЯ КАЖДОГО набора ROW NEW.created_at = UTC_TIMESTAMP (); – kgriffs 26 October 2010 в 16:21
  • 2
    Вероятно, вам лучше использовать временную метку, чем триггер для будущего здравомыслия (техническое обслуживание). Это слишком тривиальный вариант для триггера, хотя это решение. – getWeberForStackExchange 7 October 2011 в 18:50
  • 3
    Вероятно, вы захотите установить значение по умолчанию только IF NEW.created_at IS NOT NULL – Petr Peller 7 December 2011 в 12:16

Вы можете разрешить отметку времени по умолчанию. Сначала рассмотрим, какой набор символов вы используете, например, если u взял utf8, этот набор символов поддерживает все языки, и если вы взяли laten1, этот набор символов поддерживает только английский. Следующий setp, если вы работаете в рамках какого-либо проекта, должен знать часовой пояс клиента и выбирать, что вы являетесь клиентской зоной. Этот шаг является обязательным.

-2
ответ дан David Sykes 19 August 2018 в 00:29
поделиться
  • 1
    Столбцы DateTime не могут иметь значения по умолчанию. Это документально подтвержденная функция. Не все разработчики имеют доступ к изменению своей кодировки символов. И настройка сервера на его клиенты часовая зона обычно не является возможностью, особенно когда клиенты не все являются родными для одной области часового пояса. – rlb.usa 21 October 2010 в 19:39

Я думаю, что просто в mysql, поскольку mysql встроенная функция, называемая now (), которая дает текущее время (время этой вставки).

Таким образом, ваш запрос должен выглядеть аналогично

CREATE TABLE defaultforTime(
    `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
    `modification_time` DATETIME default now()
);

Спасибо.

0
ответ дан Deepak N 19 August 2018 в 00:29
поделиться

Если вы пытаетесь установить значение по умолчанию как NOW (), MySQL поддерживает, что вам нужно изменить тип этого столбца TIMESTAMP вместо DATETIME. TIMESTAMP имеет текущую дату и время по умолчанию .. я думаю, что он разрешит вашу проблему ..

0
ответ дан Dhrumil Shah 19 August 2018 в 00:29
поделиться

При определении многострочных триггеров нужно изменить разделитель, так как точка с запятой будет приниматься компилятором MySQL в качестве конца триггера и генерировать ошибку. например,

DELIMITER //
CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END//
DELIMITER ;
6
ответ дан Drawin Kumar 19 August 2018 в 00:29
поделиться

Я запускаю MySql Server 5.7.11, и это предложение:

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

не работает. Но следующее:

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '1000-01-01 00:00:00'

просто работает.

В качестве sidenote упоминается в mysql docs :

Тип DATE используется для значений с частью даты, но без временной части. MySQL извлекает и отображает значения DATE в формате «YYYY-MM-DD». Поддерживаемый диапазон: «1000-01-01» - «9999-12-31».

, даже если они также говорят:

Недействительная дата, Значения DATETIME или TIMESTAMP преобразуются в нулевое значение соответствующего типа ('0000-00-00' или '0000-00-00 00:00:00').

6
ответ дан Evhz 19 August 2018 в 00:29
поделиться

Для всех, кто использует столбец TIMESTAMP в качестве решения, я хочу, чтобы второе ограничение было из руководства:

http://dev.mysql.com/doc/refman/5.0/ ru / datetime.html

"Тип данных TIMESTAMP имеет диапазон '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07 «UTC. Он имеет разные свойства, в зависимости от версии MySQL и режима SQL, на котором работает сервер. Эти свойства описаны далее в этом разделе.»

Таким образом, это, очевидно, нарушит ваше программное обеспечение примерно за 28 лет.

Я считаю, что единственным решением на стороне базы данных является использование триггеров, как упомянуто в других ответах.

7
ответ дан Fabian 19 August 2018 в 00:29
поделиться
  • 1
    Что, если MySQL был обновлен через 20 лет и это ограничение было удалено? Я не уверен, что это возможно, а просто мысль. – NessDan 1 May 2012 в 22:00
CREATE TABLE `testtable` (
    `id` INT(10) NULL DEFAULT NULL,
    `colname` DATETIME NULL DEFAULT '1999-12-12 12:12:12'
)

В приведенном выше запросе для создания «testtable» я использовал «1999-12-12 12:12:12» в качестве значения по умолчанию для столбца DATETIME colname

2
ответ дан Fathah Rehman P 19 August 2018 в 00:29
поделиться

В версии 5.6.5 можно установить значение по умолчанию в столбце datetime и даже создать столбец, который будет обновляться при обновлении строки. Определение типа:

CREATE TABLE foo (
    `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
    `modification_time` DATETIME ON UPDATE CURRENT_TIMESTAMP
)

Ссылка: http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html

494
ответ дан Gustav Bertram 19 August 2018 в 00:29
поделиться
  • 1
    Недопустимое значение по умолчанию для 'menu_creation_time' – Fernando Trindade 10 July 2014 в 11:34
  • 2
    @FernandoTrindade Вам нужна версия MySQL 5.6.5 или новее. Вы можете увидеть, как он работает здесь: sqlfiddle.com / #! 9 / dd2be – Gustav Bertram 10 July 2014 в 11:38
  • 3
    @GustavBertram, я использую версию 5.6.22, но все же я получил ошибку следующим образом: CREATE TABLE tbl (InsertDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UpdateDate TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP (6)); Код ошибки: 1294. Недействительное предложение ON UPDATE для столбца «UpdateDate» – Manish Sapkal 15 December 2014 в 10:31
  • 4
    @ManishSapkal. Вы используете TIMESTAMP, а не DATETIME. Кроме того, не делайте его NULL. – Gustav Bertram 15 December 2014 в 10:53
  • 5
    Просто примечание - это не работает для date – Nick 10 February 2016 в 10:37

MySQL 5.6 исправил эту проблему .

ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'
12
ответ дан Hauleth 19 August 2018 в 00:29
поделиться

Для меня триггерный подход сработал лучше всего, но я нашел подлость с подходом. Рассмотрим основной триггер, чтобы установить поле даты в текущее время на вставке:

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = NOW();

Обычно это замечательно, но скажите, что вы хотите установить поле вручную с помощью инструкции INSERT, например:

INSERT INTO tblMyTable(name, dateAdded) VALUES('Alice', '2010-01-03 04:30:43');

Что происходит, так это то, что триггер немедленно перезаписывает ваше предоставленное значение для поля, и поэтому единственный способ установить не текущее время - это продолжение инструкции UPDATE - yuck! Чтобы переопределить это поведение при предоставлении значения, попробуйте этот слегка модифицированный триггер с помощью оператора IFNULL:

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = IFNULL(NEW.dateAdded, NOW());

Это дает лучшее из обоих миров: вы можете указать значение для столбца даты, и оно будет принять, и в противном случае оно будет по умолчанию текущим временем. Это все еще гетто относительно чего-то чистого, как DEFAULT GETDATE () в определении таблицы, но мы приближаемся!

127
ответ дан John Larson 19 August 2018 в 00:29
поделиться
  • 1
    +1 для подтверждения оговорки с перезаписью явных значений пользователя вставки. – Kip 27 September 2011 в 18:21
  • 2
    Я лично считаю, что это лучший способ. TIMESTAMP действительно имеет странное поведение, и я бы никогда не написал код, который имеет ограничение на 2038 год. – Eric 24 January 2012 в 20:30
  • 3
    Неважно, я понял это. Забыл установить поле, чтобы разрешить NULL. Больше никаких предупреждений. – Kaji 1 March 2012 в 16:43
  • 4
    Триггеры - это зло! Только когда-либо используйте их, когда нет другого способа сделать что-то. Лучше обновить до 5.6.x id, чем использовать триггер. – ksymeon 24 January 2015 в 01:17
  • 5
    В MySQL 5.5 IFNULL не работает в DATETIME; с помощью вышеуказанного триггера dateAdded отобразит все «0000-00-00 00:00:00». Используя это делает трюк: `ДЛЯ КАЖДОЙ ROW IF NEW.dateAdded = 0 THEN SET NEW.dateAdded = NOW (); END IF; ` – Kenney 12 June 2015 в 14:16

Возьмем, к примеру, если у меня была таблица с именем «site» с столбцом created_at и update_at, которые были и DATETIME, и теперь нужно значение по умолчанию, я мог бы выполнить следующий sql для этого.

ALTER TABLE `site` CHANGE `created_at` `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABLE `site` CHANGE `created_at` `created_at` DATETIME  NULL DEFAULT NULL;

ALTER TABLE `site` CHANGE `updated_at` `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABLE `site` CHANGE `updated_at` `updated_at` DATETIME NULL DEFAULT  NULL;

Последовательность операторов важна, поскольку таблица не может иметь двух столбцов типа TIMESTAMP со значениями по умолчанию CUREENT TIMESTAMP

0
ответ дан Joseph Persie 19 August 2018 в 00:29
поделиться

Вы можете использовать триггеры для создания этого типа.

CREATE TABLE `MyTable` (
`MyTable_ID`  int UNSIGNED NOT NULL AUTO_INCREMENT ,
`MyData`  varchar(10) NOT NULL ,
`CreationDate`  datetime NULL ,
`UpdateDate`  datetime NULL ,
PRIMARY KEY (`MyTable_ID`)
)
;

CREATE TRIGGER `MyTable_INSERT` BEFORE INSERT ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the creation date
    SET new.CreationDate = now();

        -- Set the udpate date
    Set new.UpdateDate = now();
END;

CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END;
22
ответ дан Josh Lee 19 August 2018 в 00:29
поделиться

Вы можете использовать now () для установки значения столбца datetime, но имейте в виду, что вы не можете использовать это как значение по умолчанию.

6
ответ дан KernelM 19 August 2018 в 00:29
поделиться
  • 1
    правда. Я просто попытался использовать сейчас и получил ошибку & quot; Код ошибки: 1067. Недопустимое значение по умолчанию. & Quot ;. так что ответ? ;-) – Brian Boatright 3 October 2008 в 21:31
  • 2
    Это лучшее решение для компрометации MySQL версий 5.5 и 5.6. Для версии 5.5 предопределите значение NOW() и используйте его позже для вставки. Для версии 5.6 просто установите NOW() в качестве значения по умолчанию. – Abel Callejo 4 December 2017 в 20:37

это действительно ужасная новость. здесь длинный ожидающий запрос ошибки / функции для этого . это обсуждение также говорит об ограничениях типа данных временной метки.

Я серьезно задаюсь вопросом, в чем проблема с реализацией этой вещи.

12
ответ дан Kinjal Dixit 19 August 2018 в 00:29
поделиться

Это мой пример триггера:

/************ ROLE ************/
drop table if exists `role`;
create table `role` (
    `id_role` bigint(20) unsigned not null auto_increment,
    `date_created` datetime,
    `date_deleted` datetime,
    `name` varchar(35) not null,
    `description` text,
    primary key (`id_role`)
) comment='';

drop trigger if exists `role_date_created`;
create trigger `role_date_created` before insert
    on `role`
    for each row 
    set new.`date_created` = now();

0
ответ дан Lucas Moyano Angelini 19 August 2018 в 00:29
поделиться

Используйте следующий код

DELIMITER $$

    CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROW
    BEGIN
      SET new.datefield = NOW();
    END $$

    DELIMITER ;
2
ответ дан Rana Aalamgeer 19 August 2018 в 00:29
поделиться

Если вы уже создали таблицу, вы можете использовать

. Чтобы изменить значение по умолчанию на текущее время даты

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;

Чтобы изменить значение по умолчанию на «2015-05-11 13:01:01 '

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT '2015-05-11 13:01:01';
7
ответ дан Saveendra Ekanayake 19 August 2018 в 00:29
поделиться

Вот как это сделать в MySQL 5.1:

ALTER TABLE `table_name` CHANGE `column_name` `column_name` 
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

У меня нет подсказки, почему вам нужно дважды вводить имя столбца.

5
ответ дан Udo Held 19 August 2018 в 00:29
поделиться
  • 1
    now () вместо (select now ()) будет достаточно – dimus 2 December 2011 в 02:20
  • 2
    CHANGE также предназначен для переименования поля. Имя первого столбца - «старый», второе имя столбца - «новое». Он выглядит излишним, если вы не меняете имя поля. Если это слишком эстетично, попробуйте MODIFY. – John Gordon 27 January 2012 в 22:29

Если вы пытаетесь установить значение по умолчанию как NOW (), я не думаю, что MySQL поддерживает это. В MySQL вы не можете использовать функцию или выражение как значение по умолчанию для любого типа столбца, за исключением столбца типа данных TIMESTAMP, для которого вы можете указать CURRENT_TIMESTAMP как значение по умолчанию.

3
ответ дан Vijesh VP 19 August 2018 в 00:29
поделиться
5
ответ дан Udo Held 30 October 2018 в 12:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: