2009-09-22 10 views
6

Mam tabelę jak pokazano poniżej. W celu obejścia Uchybienia teraz kolumny ograniczenie MySQL użyłem końcówki jak pokazano hereMySQL dwukolorowa sygnatura czasowa domyślnie TERAZ BŁĄD 1067

CREATE TABLE IF NOT EXISTS mytable (
    id INT NOT NULL AUTO_INCREMENT , 
    create_date TIMESTAMP NULL DEFAULT '0000-00-00 00:00:00' , 
    update_date TIMESTAMP NULL DEFAULT NOW() ON UPDATE NOW() , 
    PRIMARY KEY (`parti_id`)) 
ENGINE = InnoDB; 

Moja sql_mode nie obejmuje NO_ZERO_DATE jak wskazał here mój wynik:

mysql> SELECT @@sql_mode; 
+------------+ 
| @@sql_mode | 
+------------+ 
|   | 
+------------+ 
1 row in set (0.00 sec) 

To wciąż daje błąd przedstawiony poniżej:

ERROR 1067 (42000) at line xx in file: '/myschema.sql': Invalid default value for 'create_date' 

Używam MySQL 5.1.37 na Ubuntu

Jak mogę to naprawić? Dzięki.

Odpowiedz

12

Można mieć tylko jedenkolumnę timestamp że domyślnie CURRENT_TIMESTAMP lub NOW() na stole. Jest to dobrze znany błąd w MySQL.

Aby temu zaradzić, ustaw domyślną dla tworzonej kolumny prawidłową wartość znacznika czasu, a następnie wstaw znacznik czasu do kodu aplikacji CRUD. Użyj NOW() lub CURRENT_TIMESTAMP dla zaktualizowanej domyślnej kolumny.

referencyjny materiał: http://dev.mysql.com/doc/refman/5.1/en/timestamp.html

Aby dodatkowo zilustrować wadę MySQL w tej dziedzinie, należy rozważyć następujący kod:

CREATE TABLE testing_timestamps (
    id INT NOT NULL AUTO_INCREMENT, 
    pk_id INT NOT NULL, 
    col1 TIMESTAMP DEFAULT 0, 
    col2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY(id) 
); 

delimiter $$ 
CREATE TRIGGER testing_timestamps_trigger 
    AFTER INSERT ON testing_timestamps 
    FOR EACH ROW 
    BEGIN 
    UPDATE testing_timestamps SET col1 = NOW() WHERE id = MAX(id); 
    END; 
$$ 
delimiter ; 

INSERT INTO testing_timestamps (id) VALUES (0); 

Wyjście z tego ekranu będzie:

mysql> INSERT INTO testing_timestamps (id) VALUES (0); 
ERROR 1442 (HY000): Can't update table 'testing_timestamps' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. 

To jest bummer, ponieważ użycie wyzwalacza w tym przypadku byłoby dobrym zadaniem.

+0

To nie jest błąd, to cecha: „Dla jednej kolumny TIMESTAMP w tabeli, można przypisać aktualny znacznik czasu jako wartości domyślne i wartości automatycznej aktualizacji Możliwe jest, że bieżący datownik będzie domyślną wartością do zainicjowania kolumny, dla wartości automatycznej aktualizacji lub obu. Nie jest możliwe, aby bieżący datownik był wartością domyślną dla jednej kolumny i wartością automatycznej aktualizacji dla innej kolumny. " –

+0

Debata o tym, czy jest to" błąd ", czy nie, pozostaje, ponieważ jest to bardzo denerwujące. Dlaczego nie mogę mieć dwóch kolumn sygnatury czasowej z domyślną wartością teraz() z automatyczną aktualizacją drugiej kolumny? Odpowiedź brzmi, że MySQL tego nie robi. Tak naprawdę nie nazywam tej funkcji. –

+0

Randy dzięki za odpowiedź. Znam link, który podałeś. Po prostu szukam obejścia. Jednak wydaje się, że wszystkie sztuczki pokazane w Internecie po prostu nie działają. –

7

Właściwie kod Randy'ego jest uszkodzony. To nie zadziała, ponieważ jest wyzwalaczem mutacyjnym. Nie można zaktualizować tabeli, która zainicjowała aktualizację. Na przykład, jeśli aktualizujesz SESJE tabel, nie możesz zmienić tabeli w wyzwalaczu, używając instrukcji UPDATE, INSERT lub DELETE. Jedynym sposobem modyfikacji tabeli, do której załączony jest wyzwalacz, jest użycie przedrostków "NEW" lub "OLD", jak pokazano poniżej. (Oczywiście, możesz dowolnie aktualizować inne tabele.) Oto przykład jak przezwyciężyć problem opisany przez op.

create table sessions (
    id integer not null, 
    created timestamp not null default 0, 
    updated timestamp not null default 0 
); 

delimiter // 
create trigger bifer_sessions_ts before insert on sessions for each row 
begin 
    set new.created = now(); 
    set new.updated = now(); 
end; 
// 
create trigger bufer_sessions_ts before update on sessions for each row 
begin 
    set new.updated = now(); 
end; 
// 
delimiter ; 
1

Aby to zrobić, i to działa:

col1 TIMESTAMP DEFAULT 0, 

col2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 

Nie trzeba wyzwalacz dla col1, tylko upewnić się, że wartość jest NULL w zapytaniu. Odpowiedź znajduje się w przewodniku po certyfikacji.

0

Domyślny TIMESTAMP nie jest obsługiwany w MySQL przed wersjami 5.6.1 w tej samej tabeli.
Po wersji MySQL 5.6. + Pozwala na dwie lub więcej kolumn TIMESTAMP w tej samej tabeli.

Można spróbować aktualizacji wersji mysql