1

私はこのような「ユーザー」SQLテーブル構造を持っています(IDは特定の理由でランダムに生成され、自動インクリメントされません):

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

1つのクエリで(同じ名前を2回追加する同時クエリを回避するため)、その名前のレコードがまだなく、deleted = 0の場合は、テーブルに新しいユーザーを追加する必要があります。次に、クエリの結果を知る必要があります。 (ユーザーが追加された場合)ユーザーが追加されたかどうかを報告できるようにします。これはPHPを使用して可能ですか?

私はこれを行うことができました(しかし、もちろん、準備されたステートメントとして!):

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

しかし、ユーザーが追加されたかどうかをどのように知ることができますか?

4

3 に答える 3

2

mysqli を使用している場合は、このmysqli_stmt_affected_rows()関数を使用して、挿入された行数を判断できます。

同様に、このPDOStatement::rowCount()メソッドを使用して、PDO に挿入された行数を特定できます。

どちらの関数も、クエリの結果として挿入された行数を示します。

于 2012-06-20T22:31:37.340 に答える
2
于 2012-06-20T22:32:33.800 に答える
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;
}

そして…DBH構成:

/**
 * 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"
于 2012-06-20T22:48:33.943 に答える