代码之家  ›  专栏  ›  技术社区  ›  mrpatg

使用if的mysql语句出错@@

  •  0
  • mrpatg  · 技术社区  · 15 年前

    下面的SQL语句中似乎有错误

    $mysql = mysql_query(
        "UPDATE rsvp SET (`userid` =  '$userid' ,  `screenname` =  '$screenname' ,  
          `picture` =  '$profile_image_url' ,  `status` =  '$rsvpstatus') 
        WHERE eventid='$eventid' 
        IF @@ROWCOUNT=0 
        INSERT INTO `rsvp` (`userid`, `screenname`, `picture`, `eventid`, `status`) 
          VALUES (`$userid`, `$screenname`, `$profile_image_url`, `$eventid`, `$rsvpstatus`)"
    ) or die(mysql_error());
    

    使用MySQL5,有什么想法吗?

    3 回复  |  直到 15 年前
        1
  •  2
  •   davethegr8 Community Driven Business    15 年前

    为什么不在查询中使用替换而不使用已有的内容呢?语法与insert-into完全相同(除了replace而不是insert,duh),mysql会更新行(如果存在),如果不存在则插入行,并且都基于传递的主键。

    假设您的桌子是这样的:

    CREATE TABLE rsvp (
      userid int(11) NOT NULL default '0',
      screenname varchar(255) default NULL,
      picture varchar(255) default NULL,
      eventid int(11) NOT NULL default '0',
      status varchar(8) default NULL,
      PRIMARY KEY  (userid,eventid)
    )
    

    查询

    REPLACE INTO `rsvp` (`userid`, `screenname`, `picture`, `eventid`, `status`) 
      VALUES (`$userid`, `$screenname`, `$profile_image_url`, `$eventid`, `$rsvpstatus`)"
    

    如果userid和eventid的组合不存在,则插入该行;如果存在,则使用其他值更新该行。

        2
  •  4
  •   Bill Karwin    15 年前
    1. 不能像在update语句中那样使用括号。

    2. 这个 @@ROWCOUNT 变量是Microsoft SQL Server功能,在MySQL中不受支持。

    3. 这个 IF MySQL语法不支持您的条件。

    4. 你应该研究使用 INSERT ... ON DUPLICATE KEY UPDATE .

      MySQL还支持 REPLACE 但我不喜欢它,因为它在内部 DELETE 其次是 INSERT .这通常会产生意想不到的效果,比如创建一个新的自动增量ID、违反从属表中的引用,以及以令人困惑的方式触发删除和插入触发器。

    PS:这与您的问题无关,但我想提醒您,应该使用查询参数,而不是直接将变量插入到SQL字符串中。防止SQL注入缺陷始于你!注意ext/mysql不支持查询参数——您必须使用ext/mysqli或ext/pdo-mysql。


    下面是一个SQL脚本,演示了 更换 做一个 插入 其次是 删除 :

    CREATE TABLE foo (
      foo_id SERIAL PRIMARY KEY,
      stuff VARCHAR(10) DEFAULT 'this'
    ) TYPE=InnoDB;
    
    CREATE TABLE log (
      oper VARCHAR(10) NOT NULL,
      tablename VARCHAR(10) NOT NULL,
      pk BIGINT UNSIGNED NOT NULL
    );
    
    DELIMITER //
    CREATE TRIGGER foo_del AFTER DELETE ON foo
    FOR EACH ROW BEGIN
      INSERT INTO log VALUES ('delete', 'foo', OLD.foo_id);
    END//
    CREATE TRIGGER foo_upd AFTER UPDATE ON foo
    FOR EACH ROW BEGIN
      INSERT INTO log VALUES ('update', 'foo', OLD.foo_id);
    END//
    CREATE TRIGGER foo_ins AFTER INSERT ON foo
    FOR EACH ROW BEGIN
      INSERT INTO log VALUES ('insert', 'foo', NEW.foo_id);
    END//
    DELIMITER ;
    
    INSERT INTO foo () VALUES ();
    
    CREATE TABLE bar (
      foo_id BIGINT UNSIGNED,
      stuff VARCHAR(10) DEFAULT 'that',
      FOREIGN KEY (foo_id) REFERENCES foo(foo_id) ON DELETE CASCADE
    );
    
    INSERT INTO bar (foo_id) VALUES (LAST_INSERT_ID());
    
    SELECT * FROM foo LEFT OUTER JOIN bar USING (foo_id);
    
    REPLACE INTO foo (foo_id, stuff) VALUES (1, 'other');
    
    SELECT * FROM foo LEFT OUTER JOIN bar USING (foo_id);
    
    SELECT * FROM log;
    

    最后一个查询的输出:

    +--------+-----------+----+
    | oper   | tablename | pk |
    +--------+-----------+----+
    | insert | foo       |  1 |
    | delete | foo       |  1 |
    | insert | foo       |  1 |
    +--------+-----------+----+
    

    幸运的是,MySQL似乎已经实现了 更换 作为一个原子操作,它不会错误地删除从属表中的行。

        3
  •  1
  •   fredrik alexandresoli    15 年前

    不认为您可以在MySQL中使用@@rowcount,但有一些函数要使用,请参阅此线程: http://forums.mysql.com/read.php?60,45239,45239#msg-45239