【问题标题】:MySQL if exists (select), update, else, insert with python using date comparisonMySQL if exists (select), update, else, insert with python using date comparison
【发布时间】:2013-11-26 19:33:45
【问题描述】:

如果满足各自的条件,我正在尝试执行数据库更新,条件是多个列的值类型为 DATE 的数据库记录存在,但我似乎遇到了麻烦。任何帮助深表感谢。谢谢!

以下代码

    select_cmd = "SELECT * FROM " + self.designator + " WHERE player_fkid=" + str(fixed['player_fkid']) + \
                    " AND team_fkid=" + str(fixed['team_fkid']) + " AND season_fkid=" + str(fixed['season_fkid'])

    update_start_cmd = "UPDATE " + self.designator + " SET date_start='" + str(update['date_start']) + \
                    "' WHERE date_start>'" + str(update['date_start']) + "'"

    update_end_cmd = "UPDATE " + self.designator + " SET date_end='" + str(update['date_end']) + "' WHERE date_end<'" + \
                    str(update['date_end']) + "'"

    insert_cmd = "INSERT INTO " + self.designator + " (player_fkid, team_fkid, season_fkid, date_start, date_end) VALUES (" + \
                    str(fixed['player_fkid']) + ", " + str(fixed['team_fkid']) + ", " + str(fixed['season_fkid']) + ", '" + \
                    str(update['date_start']) + "', '" + str(update['date_end']) + "')"

    cmd = "IF EXISTS (" + select_cmd + ")" + "\n" + update_start_cmd + "\n" + update_end_cmd + "\nELSE " + insert_cmd

    try:
        cursor.execute(cmd)
        cnx.commit()
    except mysql.connector.errors.ProgrammingError:
        print "Error: invalid command '" + cmd + "'"

返回以下错误:

错误:无效命令 'IF EXISTS (SELECT * FROM roster WHERE player_fkid=1 AND team_fkid=1 AND season_fkid=1)
更新名册 SET date_start='2010-04-13' WHERE date_start>'2010-04-13'
更新名册 SET date_end='2010-04-13' WHERE date_end ELSE INSERT INTO roster (player_fkid, team_fkid, season_fkid, date_start, date_end) VALUES (1, 1, 1, '2010-04-13', '2010-04-13')'

【问题讨论】:

  • 我想补充一点,当我在 mysql 终端中一一执行上述语句时,我没有问题。不确定 \n 是否是正确的分隔符。
  • 您不能使用IF EXISTS 开始查询。
  • 您要查找的内容有点不清楚。 “在满足各自条件的情况下,在多个列中存在 DATE 类型的值的 db 记录的条件下进行更新”。你能试着更清楚地解释那部分吗?
  • 当然。对于那个很抱歉。如果满足存在条件,则执行两个更新。如果满足其条件语句,则执行第一次更新。如果满足其条件语句,则执行第二个 udpate。我已将底部的粗体错误重新格式化,以提高可读性并使其更清晰。
  • @SimeonVisser,谢谢!我为 if exists 任务找到了这个解决方案 (stackoverflow.com/questions/13373843/…)。我应该将我的更新分成两个单独的语句来执行,还是有办法将它们组合成一个?

标签: python mysql


【解决方案1】:

我发现以下方法有效:

    cmd = "SELECT COUNT(1) FROM roster WHERE player_fkid=" + str(fixed['player_fkid']) + " AND team_fkid=" + str(fixed['team_fkid']) + " AND season_fkid=" + str(fixed['season_fkid'])
    cursor.execute(cmd)
    if cursor.fetchone()[0]:
        udpate_sub_cmd = "UPDATE roster"
        date_start_sub_cmd = "SET date_start= IF(date_start > '" + str(update['date_start']) + "', '" + str(update['date_start']) + "', values(date_start)),"
        date_end_sub_cmd = "date_end= IF(date_end > '" + str(update['date_end']) + "', '" + str(update['date_end']) + "', values(date_end));"
        where_sub_cmd = "WHERE player_fkid=" + str(fixed['player_fkid']) + " AND team_fkid=" + str(fixed['team_fkid']) + " AND season_fkid=" + str(fixed['season_fkid'])
        cmd = udpate_sub_cmd + " " + date_start_sub_cmd + " " + date_end_sub_cmd + " " + where_sub_cmd
        cursor.execute(cmd, multi=True)
    else:
        insert_sub_cmd = "INSERT INTO roster (player_fkid, team_fkid, season_fkid, date_start, date_end)" 
        values_sub_cmd = "VALUES (" + str(fixed['player_fkid']) + ", " + str(fixed['team_fkid']) + ", " + str(fixed['season_fkid']) + ", '" + str(update['date_start']) + "', '" + str(update['date_end']) + "')"
        cmd = insert_sub_cmd + " " + values_sub_cmd
        cursor.execute(cmd)

使用前面提到的链接中的部分解决方案。

【讨论】:

    【解决方案2】:

    我认为您想使用 Insert... on duplicate key update 语法。
    (具体来说,conditional duplicate key updates

    类似:

    INSERT INTO roster (player_fkid, team_fkid, season_fkid, date_start, date_end) 
    VALUES (1, 1, 1, '2010-04-13', '2010-04-13')
    ON DUPLICATE KEY UPDATE
    date_start= IF(date_start > '2010-04-13', '2010-04-13', values(date_start)),
    date_end= IF(date_end > '2010-04-13', '2010-04-13', values(date_end));
    

    【讨论】:

    • 更正。我发现在这种情况下 ON DUPLICATE KEY 不能作为解决方案,因为表不能有唯一键或主键。因此,此解决方案会导致不需要的冗余条目,因为没有键被视为重复项。我目前正在使用的解决方案发布在上面(现在)。如果可以以某种方式将其作为一个语句执行而不添加新的主键,在该主键上可以利用 ON DUPLICATE KEY UPDATE,我还是有点好奇。
    猜你喜欢
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 2020-07-20
    • 2012-09-08
    • 2012-08-08
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多