2012-06-20 70 views
1

我有一个这样的“用户” SQL表结构(ID是随机因为某些原因产生的,它不是自动递增的):INSERT到如果不存在表,并返回结果

ID name  deleted lastActive 
3242 Joe  0   20-6-2012 23:14 
2234 Dave  0   20-6-2012 23:13 
2342 Simon 1   20-6-2012 23:02 
9432 Joe  1   20-6-2012 22:58 

在一个查询(以避免并发查询添加相同的名称两次),我需要添加一个新的用户到表中,如果还没有一个名称为AND AND = 0的记录,那么我需要知道查询的结果(if该用户被添加),以便我可以报告说是否添加了用户。这可能使用PHP?

我能做到这一点(但作为一个事先准备好的声明,当然!):

INSERT INTO users (ID, name) VALUES ($id, $name) 
    WHERE NOT EXISTS (SELECT 1 FROM users WHERE name = $name AND deleted = 0) 

但我怎么能知道是否加入或没有用户?

回答

2

如果您使用的是mysqli,则可以使用mysqli_stmt_affected_rows()函数确定插入的行数。

同样,您可以使用PDOStatement::rowCount()方法确定为PDO插入了多少行。

这两个函数都会告诉您作为查询结果插入的行数。

+0

完美,从来不知道这存在。谢谢! – Timm

+0

蒂姆,你很受欢迎! :) – nickb

1

下面是返回ID一个很好的插入方法:

/** 
* Execute an insert or update in the database. 
* @param $table - Table name. 
* @param $key_name - Primary key to update. NULL to a insert 
* @param $data - Column data array 
* @param $call_on_error function name that should called in case of an exception during the 
* execution of the statment, the function is expected to take one argument, the exception object 
* @return mixed An array containing the key inserted or updated on success, false on failure. 
*/ 
function INSERT($table, $key_name, &$data, $call_on_error = null) { 
    list($min_cols, $prefix, $suffix, $key_value) = isset($data[$key_name]) ? 
     array(2, 'UPDATE', " WHERE `$key_name`=:$key_name", $data[$key_name]) : 
     array(1, 'INSERT', '', null); 
    if (count($data) < $min_cols) { 
     return false; 
    } 
    $set_clause = ''; 
    foreach ($data as $k => $v) { 
     if ($k !== $key_name) { 
      if (($flag_name = strstr($k, "__", true))) { 
       if (strcmp($k, "{$flag_name}__mask") && isset($data["{$flag_name}__value"])) 
        $set_clause .= ",`$flag_name`=:{$flag_name}__value | (`$flag_name` & :{$flag_name}__mask)"; 
      } else { 
       $set_clause .= ",`$k`=:$k"; 
      } 
     } 
    } 
    global $dbo_error_duplicated; 
    $dbo_error_duplicated = false; 
    $dbh = DBH(); 
    try { 
     $sth = $dbh->prepare("$prefix $table SET " . substr($set_clause, 1) . $suffix); 
     $res = $sth->execute($data); 
    } catch (PDOException $e) { 
     $dbo_error_duplicated = $sth->errorCode() === '23000'; 
     echo $e; 
     if(isset($call_on_error)){ 
      call_user_func($call_on_error, $e); 
     } 
     $res = false; 
    } 
    if ($res) { 
     if ($key_value === null && is_numeric($id = $dbh->lastInsertId())) { 
      $key_value = $id; 
     } 
     $res = $key_value === null ? false : array($key_name => $key_value); 
    } 
    return $res; 
} 

而且......胸径配置:

/** 
* Get Data Base Handler. 
* Manual @ http://www.php.net/manual/en/pdostatement.fetch.php 
* More info @ http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/ 
* 
* @return PDO Data Base Handler 
*/ 
function DBH() { 
    global $DBH; 
    global $db_config; 

    if ($DBH === null) { 
     // throws PDOException on connection error 
     $DBH = new PDO("mysql:host=$db_config[host];dbname=$db_config[dbname]", $db_config['user'], $db_config['pass'], 
         array(PDO::ATTR_PERSISTENT => $db_config['persistent'], PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES '$db_config[encoding]'")); 
     // ask PDO to throw exceptions for any error 
     $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    } 
    return $DBH; 
} 

使用该.ini文件:

[db_config] 
persistent = true 
host  = "localhost" 
user  = "root" 
pass  = "" 
dbname  = "theDbName" 
# host  = "db.production_host.com" 
# user  = "prod_root" 
# pass  = "big4nd5tr0ngp4s5word" 
# dbname = "theDbName" 
encoding = "UTF8"