В 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 освободит память, используемую этим объектом, и выделит другую.
ВАЖНОЕ ИЗМЕНЕНИЕ: теперь это можно достичь с помощью полей 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 **
Я смог решить это, используя этот оператор 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] _ [вставить]
Для всех тех, кто потерял сердце, пытаясь установить значение DATETIME по умолчанию в MySQL, я точно знаю, как вы себя чувствуете. Итак, вот что:
ALTER TABLE `table_name` CHANGE `column_name` DATETIME NOT NULL DEFAULT 0
Тщательно наблюдайте, что я не добавил одиночных кавычек / двойных кавычек вокруг 0
Я буквально прыгаю после решения этой проблемы: D
MySQL ( до версии 5.6.5 ) не позволяет использовать функции для значений по умолчанию DateTime. TIMESTAMP не подходит из-за его нечетного поведения и не рекомендуется использовать в качестве входных данных. (См. Тип данных MySQL по умолчанию .)
Тем не менее, вы можете выполнить этот , создав триггер .
У меня есть таблицу с полем DateCreated типа DateTime. Я создал триггер в этой таблице «Before Insert» и «SET NEW.DateCreated=NOW()
», и он отлично работает.
Надеюсь, это поможет кому-то.
IF NEW.created_at IS NOT NULL
– Petr Peller
7 December 2011 в 12:16
Вы можете разрешить отметку времени по умолчанию. Сначала рассмотрим, какой набор символов вы используете, например, если u взял utf8, этот набор символов поддерживает все языки, и если вы взяли laten1, этот набор символов поддерживает только английский. Следующий setp, если вы работаете в рамках какого-либо проекта, должен знать часовой пояс клиента и выбирать, что вы являетесь клиентской зоной. Этот шаг является обязательным.
Я думаю, что просто в mysql, поскольку mysql встроенная функция, называемая now (), которая дает текущее время (время этой вставки).
Таким образом, ваш запрос должен выглядеть аналогично
CREATE TABLE defaultforTime(
`creation_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`modification_time` DATETIME default now()
);
Спасибо.
Если вы пытаетесь установить значение по умолчанию как NOW (), MySQL поддерживает, что вам нужно изменить тип этого столбца TIMESTAMP вместо DATETIME. TIMESTAMP имеет текущую дату и время по умолчанию .. я думаю, что он разрешит вашу проблему ..
При определении многострочных триггеров нужно изменить разделитель, так как точка с запятой будет приниматься компилятором MySQL в качестве конца триггера и генерировать ошибку. например,
DELIMITER //
CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
-- Set the udpate date
Set new.UpdateDate = now();
END//
DELIMITER ;
Я запускаю 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').
Для всех, кто использует столбец 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 лет.
Я считаю, что единственным решением на стороне базы данных является использование триггеров, как упомянуто в других ответах.
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
В версии 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
MySQL 5.6 исправил эту проблему .
ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'
Для меня триггерный подход сработал лучше всего, но я нашел подлость с подходом. Рассмотрим основной триггер, чтобы установить поле даты в текущее время на вставке:
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 () в определении таблицы, но мы приближаемся!
NULL
. Больше никаких предупреждений.
– Kaji
1 March 2012 в 16:43
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
Вы можете использовать триггеры для создания этого типа.
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;
Вы можете использовать now () для установки значения столбца datetime, но имейте в виду, что вы не можете использовать это как значение по умолчанию.
NOW()
и используйте его позже для вставки. Для версии 5.6 просто установите NOW()
в качестве значения по умолчанию.
– Abel Callejo
4 December 2017 в 20:37
это действительно ужасная новость. здесь длинный ожидающий запрос ошибки / функции для этого . это обсуждение также говорит об ограничениях типа данных временной метки.
Я серьезно задаюсь вопросом, в чем проблема с реализацией этой вещи.
Это мой пример триггера:
/************ 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();
Используйте следующий код
DELIMITER $$
CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROW
BEGIN
SET new.datefield = NOW();
END $$
DELIMITER ;
Если вы уже создали таблицу, вы можете использовать
. Чтобы изменить значение по умолчанию на текущее время даты
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';
Вот как это сделать в MySQL 5.1:
ALTER TABLE `table_name` CHANGE `column_name` `column_name`
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
У меня нет подсказки, почему вам нужно дважды вводить имя столбца.
Если вы пытаетесь установить значение по умолчанию как NOW (), я не думаю, что MySQL поддерживает это. В MySQL вы не можете использовать функцию или выражение как значение по умолчанию для любого типа столбца, за исключением столбца типа данных TIMESTAMP, для которого вы можете указать CURRENT_TIMESTAMP как значение по умолчанию.
DATE
? (а не столбецdatetime
). – Sajib Acharya 3 March 2016 в 22:18