使用IF @@在mysql语句中出错

时间:2009-11-10 23:44:13

标签: mysql

我的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());

使用mysql 5,有什么想法吗?

3 个答案:

答案 0 :(得分:4)

  1. 您不应该像在UPDATE语句中那样使用括号。

  2. @@ROWCOUNT变量是Microsoft SQL Server功能,MySQL不支持。

  3. MySQL语法不支持IF条件。

  4. 您应该考虑使用INSERT ... ON DUPLICATE KEY UPDATE

    MySQL也支持REPLACE语句,但我不喜欢它,因为在内部它会DELETE后跟INSERT。这通常会产生意想不到的影响,例如创建新的自动增量ID,违反从属表的引用,以及以令人困惑的方式触发删除和插入触发器。

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


    这是一个SQL脚本,用于演示REPLACE执行INSERT后跟DELETE

    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似乎已将REPLACE实现为原子操作,因此它不会错误地删除相关表中的行。

答案 1 :(得分:2)

为什么不使用REPLACE INTO查询而不是您拥有的查询。语法与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 :(得分:1)

不要认为你可以在MySQL中使用@@ ROWCOUNT,但有一些功能可供使用,请参阅此主题:http://forums.mysql.com/read.php?60,45239,45239#msg-45239