รับ ID คีย์หลักของเรกคอร์ดใหม่จากแบบสอบถามแทรก mysql หรือไม่


249

ตกลงดังนั้นช่วยบอกฉันทำข้อมูล MySQL INSERTเป็นหนึ่งในตารางของฉันและตารางมีคอลัมน์item_idที่มีการตั้งค่าและautoincrementprimary key

ฉันจะได้รับแบบสอบถามเพื่อส่งออกค่าของคีย์หลักที่สร้างขึ้นใหม่item_idในแบบสอบถามเดียวกันได้อย่างไร

ขณะนี้ฉันกำลังเรียกใช้เคียวรีที่สองเพื่อเรียกคืน id แต่นี่ดูเหมือนว่าเป็นการปฏิบัติที่ดีเนื่องจากการพิจารณานี้อาจให้ผลลัพธ์ที่ผิด ...

หากไม่สามารถทำเช่นนั้นได้วิธีปฏิบัติที่ดีที่สุดเพื่อให้แน่ใจว่าฉันได้รับรหัสที่ถูกต้องคืออะไร


1
ไม่มีวิธีใดที่จะส่งคืนสิ่งใดจากINSERTแบบสอบถามเช่นนั้น ทำไมคุณคิดว่ามันอาจให้ผลที่ผิด?
ยาขยายตัว

4
ดีถ้ากระบวนการถูกดำเนินการโดย 2 คนแยกจากกันคุณอาจได้รับรายการกระบวนการที่ทับซ้อนกันที่ฉันคิด - เนื่องจากคุณต้องดำเนินการ 2 แบบสอบถามแยกต่างหาก?
Amy Neville

ซ้ำเป็นไปได้ของแถวแทรก PHP / MySQL แล้วรับ 'id'
Jim Fell

@JimFell ใช่มันเป็นพื้นคำถามเดียวกัน แต่คนนี้มีคำตอบที่ดีมากในทั่วไป
RozzA

1
ใช้ postgresql จากนั้นทำเช่นนี้ INSERT INTO table (col1, col2) VALUES (val1, val2) การส่งกลับ id หรือ INSERT INTO table (col1, col2) VALUES (val1, val2) RETURNING * หรือ UPDATE SET SET col1 = val1, val2 = val2 คำสั่ง WHERE RETURNING id หรือ UPDATE ตาราง SET (col1, col2) = (val1, val2) คำสั่ง WHERE RETURNING id หรือ UPDATE SET SET (col1, col2) = (val1, val2) คำสั่ง
RETURNING

คำตอบ:


327

คุณต้องใช้LAST_INSERT_ID()ฟังก์ชัน: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

เช่น:

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

สิ่งนี้จะทำให้คุณได้รับPRIMARY KEYค่าของแถวสุดท้ายที่คุณแทรก:

ID ที่ถูกสร้างขึ้นจะถูกเก็บไว้ในเซิร์ฟเวอร์บนพื้นฐานต่อการเชื่อมต่อ ซึ่งหมายความว่าค่าที่ส่งคืนโดยฟังก์ชันไปยังไคลเอนต์ที่กำหนดคือค่า AUTO_INCREMENT แรกที่สร้างขึ้นสำหรับคำสั่งล่าสุดที่มีผลต่อคอลัมน์ AUTO_INCREMENT โดยไคลเอ็นต์นั้น

ดังนั้นค่าส่งกลับโดยLAST_INSERT_ID()เป็นต่อผู้ใช้และเป็นที่ได้รับผลกระทบจากคำสั่งอื่น ๆ ที่อาจจะมีการทำงานบนเซิร์ฟเวอร์จากผู้อื่น


8
ใช่ แต่จะเกิดอะไรขึ้นถ้าในระหว่างกาล (ระหว่างคิวรีในรายการกระบวนการ) มีการแทรกแถวอื่นบ้าง? มีวิธีการเขียนแบบสอบถามแทรกเพื่อให้มันออกมานี้หรือไม่
Amy Neville

ตกลงฉันเห็น ... รหัสแทรกล่าสุดของแบบสอบถามถูกบันทึกไว้แม้ว่าจะไม่ได้บันทึกผล ... $ mysqli-> insert_id
Amy Neville

27
การทำเช่นนี้จะช่วยให้คุณได้รับPRIMARY KEYมูลค่าของแถวสุดท้ายที่คุณแทรกเนื่องจากการเชื่อมต่อแต่ละการเชื่อมต่อไปยังเซิร์ฟเวอร์จะรักษาค่าของตัวเองสำหรับสิ่งนี้ ฉันได้อัปเดตคำตอบเพื่อชี้แจงนี้
Duncan Lock

ดังนั้นผู้ใช้ 3 คนจึงโพสต์แบบฟอร์มของพวกเขาพร้อมกันและฐานข้อมูลของฉันต้องป้อนพวกเขา ฉันต้องการเพิ่มแถวที่สอดคล้องกับแต่ละ ID ที่สร้างขึ้นใหม่ของ table1 ใน table2 การทำงานพร้อมกันได้รับการดูแลหรือฉันจะต้องทำด้วยตัวเองใน PHP สำหรับคำขอเขียนฐานข้อมูลขาเข้าหรือไม่?
bad_keypoints

หาก ณ จุดที่คุณทำการแทรก table1 ฐานข้อมูลจะทราบข้อมูลทั้งหมดที่คุณต้องการแทรกลงใน table2 จากนั้นคุณสามารถใช้ทริกเกอร์เพื่อทำสิ่งนี้หรือรวมสิ่งนี้ลงในแบบสอบถาม ถ้าไม่เช่นนั้นคุณจะต้องใช้ข้อความค้นหาหลายรายการ - เช่นทำใน PHP ขึ้นอยู่กับว่าข้อมูลคืออะไรและมาจากไหนสำหรับเม็ดมีดที่สอง
Duncan Lock

21

ระวัง !! ของ "LAST_INSERT_ID ()" หากพยายามคืนค่าคีย์หลักนี้ภายใน PHP

ฉันรู้ว่ากระทู้นี้ไม่ได้ติดแท็ก php แต่สำหรับใครก็ตามที่เจอคำตอบที่ต้องการคืนรหัสแทรก MySQL จากการแทรกสคริปต์ PHP โดยใช้การเรียก mysql_query มาตรฐาน - มันไม่ทำงานและไม่ชัดเจนโดยไม่ต้องจับข้อผิดพลาด SQL

mysqli ที่ใหม่กว่ารองรับการสืบค้นหลายครั้ง - ซึ่ง LAST_INSERT_ID ()จริง ๆ แล้วเป็นการสืบค้นครั้งที่สองจากต้นฉบับ

IMO แยก SELECT เพื่อระบุคีย์หลักสุดท้ายปลอดภัยกว่าฟังก์ชั่น mysql_insert_id () ที่เป็นตัวเลือกคืนค่า AUTO_INCREMENT ID ที่สร้างจากการดำเนินการ INSERT ก่อนหน้า


7
LAST_INSERT_IDเป็นฟังก์ชั่น MySQL ต่อการเชื่อมต่อ หากคุณสอบถาม ID แทรกล่าสุดอาจเป็นไปได้ว่าการเชื่อมต่อแยกต่างหากจะทำการเขียนและคุณจะมี ID ผิด
ยาระเบิดเมื่อ

@ExplosionPills mysql_insert_id()ยังทำงานบนพื้นฐานของการเชื่อมต่อ แต่ก็ยังมีพฤติกรรมแปลก ๆ ตามที่เห็นนี่stackoverflow.com/a/897374/1305910ในความคิดเห็นโดย Cliffordlife - ไม่เป็นไรเราทุกคนควรจะใช้mysqli
RozzA

คุณสามารถอธิบายสิ่งที่คุณหมายถึงเมื่อคุณอยู่ 'มันจะไม่ทำงาน'?
john ktejik

18

จากLAST_INSERT_ID()เอกสาร:

ID ที่สร้างขึ้นจะถูกเก็บไว้ในเซิร์ฟเวอร์ตามการเชื่อมต่อ

นั่นคือถ้าคุณมีการร้องขอสคริปต์แยกกันสองคำขอพร้อมกันพวกเขาจะไม่ส่งผลกระทบต่อกันและกันLAST_INSERT_ID()(เว้นแต่คุณกำลังใช้การเชื่อมต่อแบบถาวร)


2
ฉันคิดว่ามันน่าสงสัยถ้าโต๊ะของคุณมีทริกเกอร์มันที่แทรกเข้าไปในตารางอื่น .... LAST_INSERT_ID () จะคืนค่า ID ของตารางอื่น ..
bgies

15

นี่คือสิ่งที่คุณกำลังมองหา !!!

select LAST_INSERT_ID()

นี่คือทางเลือกที่ดีที่สุดของฟังก์ชั่นการใช้งานในSCOPE_IDENTITY()SQL Server

คุณต้องจำไว้ว่าสิ่งนี้จะใช้ได้Last_INSERT_ID()ก็ต่อเมื่อมีการไล่ตามInsertคำค้นหาของคุณ นั่นคือแบบสอบถามส่งคืนรหัสที่แทรกในสคีมา คุณไม่สามารถรับรหัสที่แทรกล่าสุดของตารางที่ระบุได้

สำหรับรายละเอียดเพิ่มเติมโปรดไปที่ลิงค์ฟังก์ชันเทียบเท่าของ SQLServer SCOPE_IDENTITY () ใน mySQL?


6

หากคุณต้องการค่าก่อนที่จะแทรกแถว:

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

คุณสามารถใช้สิ่งนี้ในส่วนแทรก:

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

1
อันนี้ดูเหมือนจะเป็นความคิดที่ดีใช่ไหม? หากลูกค้า 2 คนเรียกฟังก์ชั่นนั้นในเวลาเดียวกันพวกเขาจะคิดว่าพวกเขากำลังแทรกรหัสเดียวกันเมื่อในความเป็นจริงพวกเขาไม่ใช่ ... คนหนึ่งจะช้าลงเล็กน้อยในการแทรกและรับ ID ต่อไปโดยไม่ทราบ
CarCar

5

คุณจะได้รับพารามิเตอร์เหล่านี้ในผลการสืบค้นของคุณ:

    "fieldCount": 0,
    "affectedRows": 1,
    "insertId": 66,
    "serverStatus": 2,
    "warningCount": 1,
    "message": "",
    "protocol41": true,
    "changedRows": 0

insertIdคือสิ่งที่คุณต้องการ

(NodeJS-ข้อมูล MySQL)



2

เพียงใช้ "$ last_id = mysqli_insert_id ($ conn);"


2
ฉันสะดุดจริงๆที่นี่กำลังมองหาคำตอบนี้ขอบคุณ php เวอร์ชัน google ดังนั้นฉันโหวตคำตอบนี้ขึ้น ในขณะที่ทางเทคนิค OP ไม่ได้ขอ php นี่อาจเป็นประโยชน์กับคนจำนวนมากที่สะดุดที่นี่เช่นกัน
ช่างภาพ Britt

ขอบคุณ Arnav มาก! I
JuanSedano

1

หากคุณใช้ PHP: บนวัตถุPDOคุณสามารถเรียกใช้วิธีlastInsertIdอย่างง่าย ๆ หลังจากการแทรกของคุณ

มิฉะนั้นด้วยLAST_INSERT_IDคุณสามารถรับค่าเช่นนี้:SELECT LAST_INSERT_ID();



0

ฉันต้องการแบ่งปันวิธีการของฉันใน PHP คุณบางคนอาจพบว่ามันไม่ใช่วิธีที่มีประสิทธิภาพ แต่นี่เป็นวิธีที่ดีกว่า 100 ตัวเลือกอื่น ๆ

สร้างคีย์สุ่มและแทรกลงในตารางเพื่อสร้างแถวใหม่ จากนั้นคุณสามารถใช้คีย์นั้นเพื่อดึงคีย์หลัก ใช้การอัปเดตเพื่อเพิ่มข้อมูลและทำสิ่งอื่น ๆ

การทำเช่นนี้ช่วยรักษาความปลอดภัยแถวและมีคีย์หลักที่ถูกต้อง

ฉันไม่แนะนำสิ่งนี้จริงๆเว้นแต่คุณจะไม่มีตัวเลือกอื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.