【问题标题】:Change each record in a table with no primary key?更改没有主键的表中的每条记录?
【发布时间】:2010-09-21 12:44:49
【问题描述】:

我在数据库中有一个以文本形式表示日期的表(即“2008-11-09”),我想用 UNIX 时间戳替换它们。但是,我不认为 MySQL 能够自己进行转换,所以我想编写一个小脚本来进行转换。我能想到的方法包括获取表中的所有记录,遍历它们,并更新数据库记录。但是,由于没有主键,我无法轻松获得需要更新的确切记录。

有没有办法让 MySQL 在 SELECT 期间为记录分配临时 ID,以便我在执行 UPDATE 时引用它们?

【问题讨论】:

    标签: sql mysql primary-key


    【解决方案1】:

    这样不行吗?

    UPDATE
      MyTable
    SET
      MyTimeStamp = UNIX_TIMESTAMP(MyDateTime);
    

    【讨论】:

    • 自我注意:在假设它不能做之前检查MySQL是否可以做某事。谢谢。
    • 有时你只见树木不见森林。先生,我还有什么可以给您的吗? :-D
    • P.S.:注意夏令时问题。如果您的基础数据允许,请先将日期时间转换为 UTC。
    【解决方案2】:

    如果由于某种原因您必须进行迭代(其他答案涵盖了您不需要迭代的情况),我可以想到两种方法(这些不是 MySQL 特定的):

    1. 在表中添加一个自动分配编号的列。将其用作更新的 PK,然后删除该列(或将其保留以备将来使用)。

    2. 在没有定义PK的表中,只要不存在完全重复的行,就可以将整行作为复合PK;只需使用行中的每一列作为您的区别特征。即,如果表有 3 列,“名称”、“地址”和“更新”,请执行以下操作:

      UPDATE mytable SET updated = [timestamp value] WHERE name = [name] AND address = [address] AND timestamp = [old timestamp]

    许多数据访问框架都使用这种精确的策略来实现乐观并发。

    【讨论】:

      【解决方案3】:

      不,您应该能够使用单个更新语句来执行此操作。如果所有日期都是 yyyy-mm-dd 并且它们只是存储在某种文本列而不是 DATETIME 中,则您可以将数据移过来。 SQL 会是这样的:

      ALTER TABLE t ADD COLUMN dates DATETIME;
      UPDATE t set t.dates=t.olddate;
      

      这不应该依赖于 PK,因为 MySQL 可以扫描表中的每一行。 PK 成为问题的唯一情况是您需要更新单行,但该行可能不是唯一的。

      【讨论】:

        【解决方案4】:

        您可以在SELECT 期间使用 MySQL 用户变量功能生成值,但这些值不引用行;它们只是结果集的临时部分。您不能在 UPDATE 语句中使用它们。

        SET @v := 0;
        SELECT @v:=@v+1, * FROM mytable;
        

        这是我解决问题的方法。无论如何,您将不得不为您的 UNIX 时间戳创建另一列,因此您可以先添加它。然后将旧日期时间列中的值转换为 UNIX 时间戳并将其放入新列中。然后删除旧的文本日期时间列。

        ALTER TABLE mytable ADD COLUMN unix_timestamp INT UNSIGNED NOT NULL DEFAULT 0;
        
        UPDATE mytable
        SET unix_timestamp = UNIX_TIMESTAMP( STR_TO_DATE( text_timestamp, '%Y-%m-%d' ) );
        
        ALTER TABLE mytable DROP COLUMN text_timestamp;
        

        当然,在删除旧列之前,您应该确认转换已正确完成!

        UNIX_TIMESTAMP()STR_TO_DATE()

        【讨论】:

          猜你喜欢
          • 2013-01-10
          • 1970-01-01
          • 1970-01-01
          • 2015-07-22
          • 2016-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多