PHP MySQL PDO:获取最后插入的非ID行

PHP MySQL PDO:获取最后插入的非ID行,php,mysql,database,pdo,last-insert-id,Php,Mysql,Database,Pdo,Last Insert Id,我目前有一个脚本,可以在使用表单添加新元素时自动插入新数据 我用 当然是逻辑。现在我只想知道,如果表没有ID字段和自动递增字段,这是否会导致任何问题 撇开这一事实不谈,如果这意味着使用了一个糟糕的数据库结构。 我想确保这个程序在任何情况下都有效。好的数据库或坏的数据库结构。这不要紧 我的意思是,我想用数据返回该行,以便我可以搜索它 例如 1. 将新数据插入数据库 $query = $pdo->prepare("INSERT INTO `tablename` SET `data_name`=

我目前有一个脚本,可以在使用表单添加新元素时自动插入新数据

我用

当然是逻辑。现在我只想知道,如果表没有ID字段和自动递增字段,这是否会导致任何问题

撇开这一事实不谈,如果这意味着使用了一个糟糕的数据库结构。 我想确保这个程序在任何情况下都有效。好的数据库或坏的数据库结构。这不要紧

我的意思是,我想用数据返回该行,以便我可以搜索它

例如

1. 将新数据插入数据库

$query = $pdo->prepare("INSERT INTO `tablename` SET `data_name`='John', `data_familyname`='Doe', 'data_age`=45, `data_wife`='Sarah Doe'");
$query->execute();
2. 完全获取最后插入的行

///$LastID = $pdo->lastInsertId(); 
$query = $pdo->prepare("SELECT `data_name`,`data_familyname`,`data_age`,`data_wife` FROM `tablename` WHERE LAST IDFIELD = ".$pdo->lastInsertId());
$query->execute();
$row = $query->fetch();
行包含

3. 然后使用与刚才插入的数据完全相同的数据更新最后插入的行

$query = $pdo->prepare("UPDATE `tablename` SET `data_name`='Chris' WHERE `data_name`=? AND `data_familyname`=? AND 'data_age`=? AND `data_wife`=?");
$query->execute(array_values($row));
最后一个查询基本上是:

UPDATE `tablename` SET `data_name`='Chris' 
WHERE `data_name`='John' AND `data_familyname`='Doe' AND 'data_age`='45' AND `data_wife`='Sarah Doe'
当然,存在重复数据的可能性。您只想修改最后一行。这就是我的意思,如果数据库有良好的结构

但为了防止重复数据,可以添加:

行包含

重点是

步骤2 不起作用,因为我一次只做了几分钟。但是,我想知道是否有类似的函数或例程与我刚才提到的相同

希望这是明确的我想要什么

我最终的解决办法是: 结果:

Array
(
    [pdo_id]            =>      64
    [pdo_name]          =>      John Doe
    [pdo_counter]       =>      0
    [pdo_description]   =>      John Doe who served in Vietnam and every other war game as a default name
    [pdo_text]          =>      Some text BLABLA
)
但自动增量字段似乎是必不可少的

第二个解决方案,但仍然具有自动增量字段。 (由Edwin Lambregts提议)

请注意,此解决方案不是故障保护!!!因为查询选择最后插入的行。。。但无论如何!因此,如果另一个用户刚刚插入新行。。。你会看到他的意见,而不是你的。如果更新发生在两次更新之间,则可能发生这种情况。

$sth = $pdo_connection->prepare("INSERT INTO `pdo_test` SET 
                            `pdo_name`              =       'John Doe',
                            `pdo_description`       =       'John Doe who served in Vietnam and every other war game as a default name',
                            `pdo_text`              =       'Some text BLABLA'
                        ");
$sth ->execute();


$stmt               = $pdo_connection->prepare("SHOW COLUMNS FROM `pdo_test` WHERE EXTRA LIKE '%AUTO_INCREMENT%'");
$stmt->execute();
$row                = $stmt->fetch(PDO::FETCH_ASSOC);
$AutoIncrementField = $row['Field'];


$stmt               = $pdo_connection->prepare('SELECT * FROM `pdo_test` ORDER BY `'.$AutoIncrementField.'` DESC LIMIT 0,1');
$stmt->execute();
$result             = $stmt->fetch(PDO::FETCH_ASSOC);
结果是:

Array
(
    [pdo_id]            =>      67
    [pdo_name]          =>      John Doe
    [pdo_counter]       =>      0
    [pdo_description]   =>      John Doe who served in Vietnam and every other war game as a default name
    [pdo_text]          =>      Some text BLABLA
)

在不使用id的情况下,获取最后插入的记录/行当然是可能的

MySQL语法:

从表\u name中选择列\u name
按列排序\u名称说明
限制1

它只显示最后插入的记录


来源:

我不确定你的问题是什么,但为了不把你的表格搞砸,你必须实现以下几点:

  • 在桌子上有一个
    PK
    (主键)。它为您提供了唯一标识每一行的方法。它应该是唯一标识每行的字段或字段组合。理论上,
    PK
    的最佳候选对象是存储在标识实体的表中的实体的固有属性。例如,对于
    国家
    表,
    主键
    的最佳候选名称是完整的国家名称。在现实世界中,
    自动增量
    字段的发明是因为:

    • 有些表没有一列或一组列可以用作
      PK
      ;例如,一个用于存储程序生成的日志条目的表——所有条目都必须存储,即使其中一些条目是相同的;使用
      AUTO_INCREMENT
      字段为他们创建一个人工
      PK
    • PK
      的最佳候选列的类型为
      string
      (上例中为国家名称)或
      PK
      的候选列是两列或更多列的集合时,将其用作
      PK
      将对表的性能产生负面影响;人工的
      PK
      (创建为
      AUTO_INCREMENT
      integer字段)会生成更小的索引,从而提高使用它的查询的速度
  • INSERT
    上,您可以为
    PK
    生成一个值,并将其放入查询中,或者依靠数据库为您生成一个值(如果
    PK
    是一个
    自动增量
    字段)

    • 如果为
      PK
      生成一个值,则需要确保该值在表中不存在。您可以在
      INSERT
      之前检查它是否不存在,也可以尝试
      INSERT
      并检查它是否成功。即使之前进行了检查,
      INSERT
      仍可能失败,因为脚本的另一个实例可以同时运行,为
      PK
      生成和
      INSERT
      相同的值。在这种情况下,您需要生成另一个值并再次尝试插入,此工作流将重复,直到成功。这对我来说似乎不是一个好策略
    • 您可以让数据库为您的
      PK
      生成一个唯一值(通过在
      INSERT
      查询中为
      PK
      提供
      NULL
      ,或者根本不提供),然后询问它生成的值
      MySQL
      提供了用于此目的的函数。文件摘录:

      生成的ID在服务器中按每个连接进行维护。这意味着函数返回给给定客户机的值是为影响该客户机的
      AUTO\u INCREMENT
      列的最新语句生成的第一个
      AUTO\u INCREMENT
      值。此值不受其他客户端的影响,即使它们生成自己的
      AUTO_INCREMENT
      值。此行为确保每个客户端都可以检索自己的ID,而不必关心其他客户端的活动,也不需要锁或事务

      数据库负责所有事情:值是唯一的,它不会干扰试图同时插入同一个表的脚本(甚至其他代码)的其他实例;
      INSERT
      成功,
      PK
      是唯一的,我返回标识我的行而不是其他行的值

  • 拥有一个不是存储在表中的实体的固有属性的附加列对于它所产生的好处来说是一个很小的代价

    这只是一个指南和一个人工的
    自动增量
    
    $sth = $pdo_connection->prepare("INSERT INTO `pdo_test` SET 
                                `pdo_name`              =       'John Doe',
                                `pdo_description`       =       'John Doe who served in Vietnam and every other war game as a default name',
                                `pdo_text`              =       'Some text BLABLA'
                            ");
    $sth ->execute();
    
    $stmt               = $pdo_connection->query("SELECT LAST_INSERT_ID()");
    $result             = $stmt->fetch(PDO::FETCH_ASSOC);
    $lastID             = $result['LAST_INSERT_ID()'];
    
    
    $stmt               = $pdo_connection->prepare("SHOW COLUMNS FROM `pdo_test` WHERE EXTRA LIKE '%AUTO_INCREMENT%'");
    $stmt->execute();
    $row                = $stmt->fetch(PDO::FETCH_ASSOC);
    $AutoIncrementField = $row['Field'];
    
    
    $stmt               = $pdo_connection->prepare('SELECT * FROM `pdo_test` WHERE `'.$AutoIncrementField.'` = ?');
    $stmt->execute(array($lastID));
    $result             = $stmt->fetch(PDO::FETCH_ASSOC);
    
    echo print_r($result);
    
    Array
    (
        [pdo_id]            =>      64
        [pdo_name]          =>      John Doe
        [pdo_counter]       =>      0
        [pdo_description]   =>      John Doe who served in Vietnam and every other war game as a default name
        [pdo_text]          =>      Some text BLABLA
    )
    
    $sth = $pdo_connection->prepare("INSERT INTO `pdo_test` SET 
                                `pdo_name`              =       'John Doe',
                                `pdo_description`       =       'John Doe who served in Vietnam and every other war game as a default name',
                                `pdo_text`              =       'Some text BLABLA'
                            ");
    $sth ->execute();
    
    
    $stmt               = $pdo_connection->prepare("SHOW COLUMNS FROM `pdo_test` WHERE EXTRA LIKE '%AUTO_INCREMENT%'");
    $stmt->execute();
    $row                = $stmt->fetch(PDO::FETCH_ASSOC);
    $AutoIncrementField = $row['Field'];
    
    
    $stmt               = $pdo_connection->prepare('SELECT * FROM `pdo_test` ORDER BY `'.$AutoIncrementField.'` DESC LIMIT 0,1');
    $stmt->execute();
    $result             = $stmt->fetch(PDO::FETCH_ASSOC);
    
    Array
    (
        [pdo_id]            =>      67
        [pdo_name]          =>      John Doe
        [pdo_counter]       =>      0
        [pdo_description]   =>      John Doe who served in Vietnam and every other war game as a default name
        [pdo_text]          =>      Some text BLABLA
    )