从mysql插入查询中获取新记录主键ID?

时间:2013-06-14 16:10:38

标签: mysql insert key auto-increment

好的,让我说我在我的一个表中做了一个mysql INSERT,该表的列item_id设置为autoincrementprimary key

如何让查询在同一查询中输出新生成的主键item_id的值?

目前我正在运行第二个查询以检索id,但考虑到这可能会产生错误的结果,这似乎不太好看......

如果无法做到这一点,那么确保我检索正确ID的最佳做法是什么?

14 个答案:

答案 0 :(得分:254)

您需要使用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()返回的值是每个用户,并且不受影响可能正在服务器上运行的其他查询来自其他用户

答案 1 :(得分:18)

当心!!如果尝试在PHP中返回此主键值,则为“LAST_INSERT_ID()”

我知道这个帖子没有被标记为php,但是对于任何遇到这个答案的人来说,希望使用标准的mysql_query调用从PHP脚本插件返回一个MySQL插入ID - 它不会工作,并且在没有捕获SQL错误的情况下不明显。 / p>

较新的mysqli支持多个查询 - LAST_INSERT_ID()实际上是来自原始查询的第二个查询。

IMO单独的SELECT用于标识最后一个主键比可选的mysql_insert_id()函数更安全,该函数返回从先前的INSERT操作生成的AUTO_INCREMENT ID。

答案 2 :(得分:15)

来自LAST_INSERT_ID()文档:

  

生成的ID在每个连接的基础上在服务器中维护

即如果您同时对脚本提出两个单独的请求,它们不会影响彼此的LAST_INSERT_ID()(除非您使用的是持久连接)。

答案 3 :(得分:14)

这就是你要找的东西!!!

select LAST_INSERT_ID()

这是SCOPE_IDENTITY()中使用的SQL Server函数的最佳替代方法。

您还需要记住,只有在您Last_INSERT_ID()查询后触发Insert时才会有效。 即查询返回模式中插入的id。您无法获取特定表的最后插入ID。

有关详情,请浏览The equivalent of SQLServer function SCOPE_IDENTITY() in mySQL?

链接

答案 4 :(得分: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'
);

答案 5 :(得分:2)

您将在查询结果中收到以下参数:

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

insertId正是您所需要的。

(的NodeJS MySQL的)

答案 6 :(得分:2)

您需要在交易中使用LAST_INSERT_ID()函数:

START TRANSACTION;
  INSERT INTO dog (name, created_by, updated_by) VALUES ('name', 'migration', 'migration');
  SELECT LAST_INSERT_ID();
COMMIT;

http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

此函数将返回表中最后插入的主键。

答案 7 :(得分:1)

只需使用“ $ last_id = mysqli_insert_id($ conn);”

答案 8 :(得分:0)

如果您使用的是PHP:在PDO对象上,您可以简单地调用 插入后的lastInsertId方法。

否则,使用LAST_INSERT_ID可以得到如下值:SELECT LAST_INSERT_ID();

答案 9 :(得分:0)

如果在使用pymysql的python中,则可以从游标中使用cursor.lastrowid

答案 10 :(得分:0)

解决此问题的最佳方法是让您的代码生成随机uuid,然后将此uuid用作INSERT查询的主键ID。到那时,您的代码已经知道uuid是“最后插入的ID”,您可以在其他MySQL查询中重用它。该ID保证是唯一的,因此您不会发生冲突。确保为您的uuid列创建一个主索引

答案 11 :(得分:0)

我将firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<AdminMessage, AdminChatViewHolder>(firebaseRecyclerOptions) { @Override protected void onBindViewHolder(@NonNull final AdminChatViewHolder adminChatViewHolder, int i, @NonNull AdminMessage adminMessage) { adminChatViewHolder.getTvMessage().setText(adminMessage.getMessage()); //We retrieve the userUid to get real time name FirebaseDatabase.getInstance().getReference().child("admin").child(adminMessage.getSenderUid()).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { if (dataSnapshot.exists()) { Admin admin = dataSnapshot.getValue(Admin.class); if (admin != null) { final String nameAdmin = admin.getFullName(); final String profileUrl = admin.getProfileUrl(); //And then display adminChatViewHolder.getTvName().setText(nameAdmin); //Check for image if null or not (profileUrl) if (profileUrl != null) { Glide.with(getApplicationContext()) .load(profileUrl) .into(adminChatViewHolder.getImageView()); } } } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }); } @NonNull @Override public AdminChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view; if (viewType == VT_SENDER) { view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_admin_message_sender, parent, false); } else { view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_admin_message_receiver, parent, false); } return new AdminChatViewHolder(view); } @Override public void onDataChanged() { progressBar.setVisibility(View.GONE); } @Override public int getItemViewType(int position) { if (getItem(position).getSenderUid().equals(userUid)) { return VT_SENDER; } return VT_RECEIVER; } }; 用于Codeigniter

答案 12 :(得分:0)

这样做:

$idc = DB::table('tb_clients')->insertGetId([
                'ide'                   => $ide,
                'nome'                  => $nome,
                'email'                 => $email 
            ]);

在 $idc 上你会得到最后一个 id

答案 13 :(得分:-2)

我只想在PHP中分享我的方法,其中一些人可能发现这不是一种有效的方法,但比其他可用选项要好100。

生成一个随机密钥,并将其插入到表中以创建新行。 那么您可以使用该键来检索主键。 使用更新来添加数据和做其他事情。

这样做可以帮助保护行并拥有正确的主键。

除非您没有其他选择,否则我真的不建议这样做。