简体   繁体   中英

PHP PDO prepared statement is not executing

I am trying to learn PDO, go easy on me. I have tried searching and haven't found anything that helps - I'm probably searching for the wrong thing - and I've been scratching my head over this for hours.

I have a PDO prepared statement which doesn't seem to be executing.

I have 3 relevant database tables:

create table users (
    id int not null auto_increment primary key,
    username varchar(60),
    password varchar(60)
);

create table stats (
    id int not null auto_increment primary key,
    display_name text,
    short_name varchar(10)
);

insert into stats (display_name, short_name) values ('Magic', 'mag');
insert into stats (display_name, short_name) values ('Attack', 'atk');
insert into stats (display_name, short_name) values ('Defence', 'def');

create table user_stats (
    id int not null auto_increment primary key,
    user_id int,
    stat_id int,
    value text /* some none numerical "stats" */
);

I've added a few users while testing the registration/login system, the other two tables are as above.

Here is the function to assign a stat to a user:

function assignStatToUser($connection, $stat_name, $user_id) {

    $query = $connection->prepare('select id from stats where display_name = :name or short_name = :short');
    $query->bindParam(':name', $stat_name);
    $query->bindParam(':short', $stat_name);
    $query->execute();

    $stat_id = $query->fetchColumn(); // id - $stat_name

    echo $stat_id; // testing

    // var_dump($stat_id);

    // the above works fine

    try {

        $insert = $connection->prepare('insert into user_stats (user_id, stat_id, value) values (:user, :stat, :val)');
        $insert->bindParam(':user', $user_id);
        $insert->bindParam(':stat', /* (int) */ $stat_id);
        $insert->bindParam(':val', '0');
        $insert->execute();

    } catch (PDOException $e) {

        die($e->getMessage());

    }

}

assignStatToUser($connection, 'def', '10');

It is the second query that is not executing, the insert into query. I can't seem to figure out what I'm doing wrong. I have written and rewritten this, with and without try...catch , with backticks around the column names, passing in $user_id as a string or an integer.. not sure where I'm going wrong.

Solution

My problem was trying to insert a value directly into the value column using bindParam(':val', '0') - when I changed this line to: bindParam(':val', $value) and then the following, it worked - thanks to Zhorov for showing me the way:

function assignStatToUser($connection, $stat_name, $user_id, $value) {

    . . . .

}

What I think is your problem is the fact, that the value for your 3rd parameter in bindParam() is passed as a value, but it should be a variable. You are directly passing the value, which is not allowed. I'm able to reproduce this error with PHP 7.1.2 and PDO PHP Driver for SQL Server 4.0.3.

You have two options: 1) Define a variable and pass that variable to bindParam() or 2) Use bindValue() for your 3rd parameter. You also need to include exception handling.

Working example:

<?php
# Connection info
$hostname = 'server\instance,port';
$dbname   = 'dbname';
$username = 'username';
$password = 'password';

# Connection
try {
    $dbh = new PDO("sqlsrv:server=$hostname;Database=$dbname", $username, $password);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) {
    die( "Error connecting to SQL Server. ".$e->getMessage());
}

# Statement
try {
    $user_id = 123;
    $stat_id = 321;
    $val     = '000';
    $stmt = $dbh->prepare('insert into user_stats (user_id, stat_id, value) values (:user, :stat, :val)');
    $stmt->bindParam(':user', $user_id);
    $stmt->bindParam(':stat', $stat_id);
    $stmt->bindParam(':val', $val);         // OK, using bindParam() and a variaable
    //$stmt->bindValue(':val', '111');      // OK, using bindValue()
    //$stmt->bindParam(':val', '0');        // Error
    $stmt->execute();
} catch( PDOException $e ) {
    die( "Error connecting to SQL Server".$e->getMessage() );
}
$stmt = null;

# End
$dbh = null;
?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM