2014-12-15 15 views
8

Napisałem MySQL StoredProcedure, aby utworzyć i zwrócić nowy identyfikator dla każdej wartości tabeli, jednak otrzyma on błędną wartość na last_insert_id() z MySQL WorkBench i aplikacji Java.MYSQL LAST_INSERT_ID nie działa zgodnie z przeznaczeniem. Jak naprawić?

Ta procedura będzie wywoływana z wielu sesji.

CALL `GET_NEW_ID`('test', @test); 
select @test; 

Daje mi "141215000000", a to oznacza, że ​​last_insert_id() zwraca 0 cały czas. Widzę, że poprawnie wstawia nowe dane do seq_data.

CREATE PROCEDURE `GET_NEW_ID`(IN V_TABLE VARCHAR(10), OUT V_ID VARCHAR(12)) 
BEGIN 

    INSERT INTO seq_data (id, `name`, `stat_date`) 
    SELECT IFNULL(MAX(id), 0)+1, V_TABLE, DATE_FORMAT(NOW(),'%Y%m%d') FROM seq_data WHERE name = V_TABLE AND stat_date = DATE_FORMAT(NOW(),'%Y%m%d'); 
    SET V_ID = concat(DATE_FORMAT(NOW(),'%y%m%d'),LPAD(LAST_INSERT_ID(), 6, '0')); 

END 

Tabela wygląda następująco.

CREATE TABLE `seq_data` (
    `id` int(6) NOT NULL AUTO_INCREMENT, 
    `name` varchar(20) COLLATE utf8_bin NOT NULL, 
    `stat_date` varchar(8) COLLATE utf8_bin NOT NULL, 
    PRIMARY KEY (`id`,`name`,`stat_date`) 
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

Moim celem jest jak ...

CALL `GET_NEW_ID`('test', @test); 
select @test; 

powrót 141215000001

CALL `GET_NEW_ID`('test', @test); 
select @test; 

powrót 141215000002

CALL `GET_NEW_ID`('hello', @test); 
select @test; 

powrót 141215000001

Odpowiedz

4

Jak podano w MySQL documentation, LAST_INSERT_ID() zwraca wartość BIGINT (64-bit) reprezentującą pierwszą automatycznie wygenerowaną wartość, która została ustawiona dla kolumny AUTO_INCREMENT przez ostatnio wykonaną instrukcję INSERT, aby wpłynąć na taką kolumnę.

W twoim przypadku, wstawiasz identyfikator, więc wartość AUTO_INCREMENT nie jest generowany, więc LAST_INSERT_ID zwraca 0.

Można spróbować czegoś takiego:

CREATE PROCEDURE `GET_NEW_ID`(IN V_TABLE VARCHAR(10), OUT V_ID VARCHAR(12)) 
BEGIN 

    INSERT INTO seq_data (`name`, `stat_date`) 
    SELECT V_TABLE, DATE_FORMAT(NOW(),'%Y%m%d') FROM seq_data WHERE name = V_TABLE AND stat_date = DATE_FORMAT(NOW(),'%Y%m%d'); 
    SET V_ID = concat(DATE_FORMAT(NOW(),'%y%m%d'),LPAD(LAST_INSERT_ID(), 6, '0')); 

END 
+0

Dzięki @Dondon na odpowiedź. Ale już próbowałem, a powodem wstawienia id jest uzyskanie nowego identyfikatora dla innej kolumny "nazwa". Na przykład, jeśli chcę uzyskać nowy identyfikator dla hello tabeli, jego identyfikator nie rozpocznie się od 1, ponieważ istnieje inny identyfikator 1 dla tabeli testowej. – handicop

+0

Znów, dziękuję @Dodon, to wyjaśnia, dlaczego to nie działa tak jak zamierzałem, potrzebuję znaleźć obejście, aby rozwiązać problem. – handicop

+2

@handicop Robisz to źle. Generowanie nowego ID samemu i * wtedy * wstawienie go ręcznie nie jest poprawną odpowiedzią. Pomija wymagania dotyczące transakcji na początek. Nie powinieneś nawet * mieć * procedury 'GET_NEW_ID()'. Powinno to nastąpić automatycznie jako efekt uboczny "INSERT" w tabeli z klawiszem "AUTO_INCREMENT". – EJP

Powiązane problemy