2013-06-14 39 views
136

Ok, vì vậy hãy nói rằng tôi đang làm một mysql INSERT vào một trong các bảng của tôi và bảng có cột item_id được đặt thành autoincrementprimary key.Lấy ID khóa chính của bản ghi mới từ truy vấn chèn mysql?

Làm cách nào để nhận truy vấn xuất ra giá trị của khóa chính mới được tạo item_id trong cùng một truy vấn?

Hiện nay tôi đang chạy một truy vấn thứ hai để lấy id nhưng điều này hầu như không có vẻ như thực hành tốt xem xét điều này có thể tạo ra kết quả sai ...

Nếu đây là không thể thực hiện sau đó những gì là thực hành tốt nhất để đảm bảo Tôi lấy đúng id?

+1

Không có cách nào để trả lại bất kỳ thứ gì từ truy vấn 'INSERT' như thế; tại sao bạn nghĩ rằng nó có thể tạo ra kết quả sai? –

+3

Vâng, nếu quá trình được thực hiện bởi 2 người một cách riêng biệt thì bạn có thể nhận được một danh sách quá trình chồng chéo mà tôi nghĩ - vì bạn phải thực hiện 2 truy vấn riêng biệt? –

+0

Có thể trùng lặp của [PHP/MySQL chèn hàng sau đó nhận được 'id'] (http://stackoverflow.com/questions/897356/php-mysql-insert-row-then-get-id) –

Trả lời

183

Bạn cần phải sử dụng LAST_INSERT_ID() chức năng: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

Ví dụ:

INSERT INTO table_name (col1, col2,...) VALUES ('val1', 'val2'...); 
SELECT LAST_INSERT_ID(); 

này sẽ giúp bạn trở lại giá trị PRIMARY KEY của hàng cuối cùng mà bạn chèn vào:

ID được tạo ra được duy trì trên máy chủ trên cơ sở mỗi kết nối . Điều này có nghĩa là giá trị trả về bởi hàm cho một máy khách đã cho là giá trị AUTO_INCREMENT đầu tiên được tạo cho câu lệnh gần đây nhất ảnh hưởng đến cột AUTO_INCREMENT bởi máy khách đó.

Vì vậy, điều này không bị ảnh hưởng bởi các truy vấn khác có thể đang chạy trên máy chủ từ người dùng khác.

+6

có nhưng nếu trong thời gian tạm thời (giữa các truy vấn trong danh sách quy trình) một số hàng khác đã được chèn vào? Có cách nào để viết truy vấn chèn để nó kết quả đầu ra này? –

+0

Ok, tôi hiểu ... id chèn cuối cùng của truy vấn được ghi lại ngay cả khi nó không được đăng nhập vào kết quả ... $ mysqli-> insert_id –

+12

Điều này sẽ giúp bạn quay lại giá trị 'PRIMARY KEY' của hàng mà * bạn * chèn vào, bởi vì nó cho mỗi kết nối - mỗi kết nối đến máy chủ sẽ duy trì giá trị riêng của nó cho việc này. Tôi đã cập nhật câu trả lời để làm rõ điều này. –

12

Từ các tài liệu LAST_INSERT_ID():

ID được tạo ra được duy trì trong các máy chủ trên cơ sở mỗi kết nối

Đó là nếu bạn có hai yêu cầu riêng biệt để kịch bản đồng thời, chúng sẽ không ảnh hưởng đến nhau LAST_INSERT_ID() (trừ khi bạn đang sử dụng kết nối liên tục).

13

Đây là những gì bạn đang tìm kiếm !!!

select LAST_INSERT_ID() 

Đây là lựa chọn tốt nhất của SCOPE_IDENTITY() chức năng được sử dụng trong SQL Server.

Bạn cũng cần lưu ý rằng điều này sẽ chỉ hoạt động nếu Last_INSERT_ID() được kích hoạt sau truy vấn Insert của bạn. Đó là truy vấn trả về id được chèn vào trong lược đồ. Bạn không thể nhận được id được chèn vào cuối cùng của bảng cụ thể.

Để biết thêm chi tiết xin vui lòng đi qua các liên kết The equivalent of SQLServer function SCOPE_IDENTITY() in mySQL?

13

BEWARE !! của "LAST_INSERT_ID()" nếu cố gắng trả lại giá trị khóa chính này trong PHP.

Tôi biết chủ đề này không được gắn thẻ php, nhưng đối với bất kỳ ai đã xem câu trả lời này đang tìm cách trả lại mã chèn MySQL từ một đoạn mã PHP bằng cách sử dụng lệnh mysql_query tiêu chuẩn - nó không hoạt động và không rõ ràng mà không bắt lỗi SQL.

mysqli mới hơn hỗ trợ nhiều truy vấn - trong đó LAST_INSERT_ID() thực sự là truy vấn thứ hai từ bản gốc.

IMO một SELECT riêng biệt để xác định khoá chính cuối cùng là an toàn hơn hàm mysql_insert_id() tùy chọn trả về ID AUTO_INCREMENT được tạo từ thao tác INSERT trước đó.

+4

'LAST_INSERT_ID' là một hàm kết nối MySQL. Nếu bạn truy vấn cho ID chèn cuối cùng thì có thể một kết nối riêng biệt sẽ thực hiện ghi và bạn sẽ có ID sai. –

+0

@ExplosionPills 'mysql_insert_id()' cũng hoạt động trên cơ sở mỗi kết nối, nhưng nó cũng bị hành vi lạ như được thấy ở đây http://stackoverflow.com/a/897374/1305910 trong bình luận của Cliffordlife - không bao giờ chúng ta nên có Tôi sử dụng 'mysqli' – RozzA

-6

Nếu LAST_INSERT_ID() là hành động một chút lạ hoặc không làm việc như nó là dành cho sau đó tôi sử dụng tuyên bố đơn giản này ...

--- INSERT STATEMENT GOES HERE --- SELECT id FROM table ORDER BY id DESC LIMIT 1;

này sẽ trả về ID lớn nhất trong bảng, do đó ID cuối cùng chèn

+2

Tôi nghĩ nếu bạn có nhiều chủ đề chèn vào bảng, bạn có thể nhận được ID giống như một người khác đôi khi nếu bạn không thể hoàn thành INSERT và SELECT đủ nhanh, và mức cô lập của bạn quá thấp. –

+0

điều này bị 'điều kiện chủng tộc' – RozzA

3

Nếu bạn cần các giá trị trước khi chèn một hàng:

CREATE FUNCTION `getAutoincrementalNextVal`(`TableName` VARCHAR(50)) 
    RETURNS BIGINT 
    LANGUAGE SQL 
    NOT DETERMINISTIC 
    CONTAINS SQL 
    SQL SECURITY DEFINER 
    COMMENT '' 
BEGIN 

    DECLARE Value BIGINT; 

    SELECT 
     AUTO_INCREMENT INTO Value 
    FROM 
     information_schema.tables 
    WHERE 
     table_name = TableName AND 
     table_schema = DATABASE(); 

    RETURN Value; 

END 

bạn có thể sử dụng điều này trong một chèn:

INSERT INTO 
    document (Code, Title, Body) 
VALUES (    
    sha1(concat (convert (now() , char), ' ', getAutoincrementalNextval ('document'))), 
    'Title', 
    'Body' 
); 
+0

Điều này dường như không phải là một ý tưởng hay? Nếu 2 khách hàng gọi chức năng đó cùng một lúc, họ sẽ nghĩ rằng họ đang chèn cùng một id khi trong thực tế họ không .... một sẽ hơi chậm trên chèn và nhận được ID tiếp theo mà không có nó biết. – CarCar

+0

Bạn sẽ sử dụng mã này bên trong một giao dịch. –

Các vấn đề liên quan