Home » Php » php – How to bind PDO values for queries involving MySQL Date and Time types

php – How to bind PDO values for queries involving MySQL Date and Time types

Posted by: admin February 25, 2020 Leave a comment

Questions:

I have a db with two respective tables for DATES . . .

CREATE TABLE `dates` (
     `did` int(11) NOT NULL,
     `date` date NOT NULL
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

and TIMES . . .

CREATE TABLE `times` (
  `tid` int(11) NOT NULL,
  `time` time NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

I’m trying to bind date and time values collected from HTML date/time input fields to queries that will check if the respective date/time already exists its table. If it doesn’t, my code runs another query that inserts said date/time into the corresponding table.

$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );

$date = isset($data['date']) ? $data['date'] : NULL;
$time = isset($data['time']) ? $data['time'] : NULL;

If(isset($date)){
    $sqlDs = "SELECT * FROM `dates` WHERE date=:date";
    $stDs = $conn->prepare ( $sqlDs );
    $stDs->bindValue(':date', $date);
    $stDs->execute();
    $rDs = $stDs->fetch(PDO::FETCH_ASSOC);
    If(! $rDs ){
        $sqlDi = "INSERT INTO `dates` (date) VALUES (:date)";
        $stDi = $conn->prepare ( $sqlDi );
        $stDi->bindValue(':date', $date);
        If ($stDi->execute()){
            $dCode = $conn->lastInsertId();
            $msg['temp'] = 'success';
            $msg['body'] = $msg['body'].$date.' added to Dates.';
        }Else{
            $msg['temp'] = 'error';
            $body = isset($msg['body']) ? $msg['body'] : '';
            $msg['body'] = $body.'Date at '.$date.' didn`t work.';
        }
    }Else{
        $dCode = $rDs['did'];
        }
    }

    If(isset($time)){
        $sqlTs = "SELECT * FROM `times` WHERE time=:time";
        $stTs = $conn->prepare ( $sqlTs );
        $stTs->bindValue(':time', $time);
        $stTs->execute();
        $rTs = $stTs->fetch(PDO::FETCH_ASSOC);
        If(! $rTs ){
            $sqlTi = "INSERT INTO `times` (time) VALUES (:time)";
            $stTi = $conn->prepare ( $sqlTi );
            $stTi->bindValue(':time', $time);
            If ($stTi->execute()){
                $tCode = $conn->lastInsertId();
                $msg['temp'] = 'success';
                $msg['body'] = $msg['body'].$time.' added to Times.';
            }Else{
                $msg['temp'] = 'error';
                $body = isset($msg['body']) ? $msg['body'] : '';
                $msg['body'] = $body.'Time for '.$time.' didn`t work.';
            }
        }Else{
            $tCode = $rTs['tid'];
        }

    }

I can’t seem to figure out the right way to bind these values with the correct format for MySQL. No strtotime() syntax or anything else I’ve come across so far has worked. Is there perhaps something else I’m missing? I know I should figure this out myself but I’m coming up on the end of this project and I’m just so tired of wrestling with it.

UPDATE: I forgot to execute the SELECT queries. This code works now.

How to&Answers:
    $sqlDi = "INSERT INTO `dates`(:date)";

This isn’t correct syntax for the INSERT statement.

The correct syntax is:

INSERT INTO tablename (col1, ...) VALUES (value, ...)

MySQL supports an alternative (non-standard) syntax that I find a little easier:

INSERT INTO tablename SET col1 = value1, col2 = value2, ...

You can’t use bind parameters for column names, only for values. INSERT INTO dates (:date) is incorrect for this reason, because the parenthesized list following the table name is for column names.

The other advice I would have is to check the return value of prepare() before you assume the query parsing was successful. If you had done this, you would have known you had a syntax error.

 $stDi = $conn->prepare ( $sqlDi );
 if ($stDi === false) {
     error_log(print_r($conn->errorInfo(), true));
     error_log("SQL = [$sqlDi]");
     die("A database error occurred, please report to the site administrator");
 }