MYSQL: как создать таблицу MySQL, чтобы значение поля по умолчанию было выходом функции - PullRequest
1 голос
/ 17 июля 2009

ВОПРОС Как создать таблицу MySQL таким образом, чтобы значение поля по умолчанию было выходом функции.

Можно ли это сделать без триггера вставки?

ОБЩАЯ ИНФОРМАЦИЯ: Некоторые объекты и группы, к которым они принадлежат, должны наблюдаться ежедневно.

Для этого я создал следующую таблицу MySQL:

CREATE TABLE entity (
    entity_id  VARCHAR(10) NOT NULL,
    group_id   VARCHAR(10) NOT NULL,
    first_seen DATE        NOT NULL,
    last_seen  DATE        NOT NULL,
    PRIMARY KEY (entity_id,group_id)
)

Сценарий ежедневно анализирует журналы сущностей и записывает их в entity_raw, затем я хочу обновить таблицы, используя

REPLACE INTO entity (entity_id,group_id,last_seen) 
SELECT entity_id,group_id,record_date 
  FROM entity_raw 
 WHERE (record_date = DATE(DATE_SUB(NOW(),INTERVAL 1 DAY))

Естественно, я получаю сообщение об ошибке при добавлении новых пар (entity_id, group_id), поскольку first_seen не может быть NULL ...

Можно ли это сделать одним оператором, если не использовать триггер (мне они не нравятся, слишком удивительно для обслуживания)

или мне нужно сначала выбрать для существования, а затем вставить / обновить соответственно?

Ответы [ 4 ]

2 голосов
/ 17 июля 2009

Нет, то, что вы спрашиваете, невозможно без триггеров. Единственный пример в MySQL, где полю можно присвоить значение по умолчанию из функции, - это тип TIMESTAMP, который может иметь CURRENT_TIMESTAMP по умолчанию.

1 голос
/ 17 июля 2009

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

Итак, я бы лучше использовал оператор INSERT... ON DUPLICATE KEY UPDATE:

INSERT INTO entity (entity_id,group_id,first_seen,last_seen) 
SELECT entity_id,group_id,record_date, record_date 
    FROM entity_raw 
    WHERE (record_date = DATE(DATE_SUB(NOW(),INTERVAL 1 DAY))
ON DUPLICATE KEY UPDATE last_seen = VALUES(last_seen)

с уникальным индексом en entity_id и / или group_id. Это будет перезаписывать только last_seen, если найдена существующая строка.

1 голос
/ 17 июля 2009

Если честно, практически невозможно объединить обновление или вставить в одну инструкцию.

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

В противном случае триггер или хранимая процедура выполнят эту работу.

0 голосов
/ 17 июля 2009

После некоторого поиска я придумал это ... это решает мою "проблему", но не вопрос, который я задал: - (

REPLACE INTO entity (entity_id,group_id,first_seen,last_seen) 
SELECT r.entity_id              AS entity_id
     , r.group_id               AS group_id
     , ISNULL( e.first_seen
              ,r.record_date
             )                  AS first_seen
     , r.record_date            AS last_seen
  FROM entity_raw r
  LEFT OUTER JOIN entity e ON (    r.entity_id=e.entity_id 
                               AND r.group_id=e.group_id
                              )
 WHERE (record_date = DATE(DATE_SUB(NOW(),INTERVAL 1 DAY))

Первоначальная вставка должна быть сделана с отключенным предложением where (в таблице entity_raw уже было 5 недель данных)

...