Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble Creating a MySQL Function through PDO

Tags:

sql

php

mysql

pdo

I've created a CLI PHP script designed to allow me to run update scripts against my database. The script works as expected, runs sequential update files, rolls back on errors, etc. However, the only thing I can't get it to do properly is create functions. What am I missing?


Script

Here's the basics of how the script works:

$sql = file_get_contents($file);
$sql = "USE `$database`;" . $sql;
$stmt = $pdo->prepare($sql);

try
{
    $stmt->execute();

    if($stmt->errorCode() !== '00000')
    {
        throw new Exception("Error: Unable to run update $file\n" . print_r($stmt->errorInfo(), true));
    }
}
catch(Exception $ex)
{
    $pdo->rollBack();
    echo "Error: Exception occured running update $file\n" . print_r($ex, true) . "\n";
    throw $ex;
}

SQL

And here's an example of the Function portions of the SQL code:

DELIMITER ;;
CREATE DEFINER=CURRENT_USER FUNCTION `uuid_from_bin`(b BINARY(16)) RETURNS char(36) CHARSET latin1
    DETERMINISTIC
BEGIN
  DECLARE hex CHAR(32);
  SET hex = HEX(b);
  RETURN LOWER(CONCAT(LEFT(hex, 8), '-', MID(hex, 9,4), '-', MID(hex, 13,4), '-', MID(hex, 17,4), '-', RIGHT(hex, 12)));
RETURN 1;
END ;;

If I run this code inside MySQL Workbench it runs as expected. When I run it through my script using PDO everything except the functions are created and populated. I get no errors and no exceptions.


So Far...

I've tried removing the definer, thinking that the user that was "CURRENT_USER" might be 'user@randomip' and the user in the system is defined as 'user@%'.

I also just removed the definer from the SQL. Still works in MySQL Workbench, but not in this script.

I've also pulled the Functions out into their own SQL, same result.


Other Info

MySQL 5.5.37-0ubuntu0.14.04.1

PHP 5.5

When I connect with PDO I'm not setting the DB, since the script may need to create the database. But the scripts are appended with a USE statement. Again all the other DDL statements work.

The user has all but Grant permissions on schema based on a pattern, specifically ci_%


Solution, Update DELIMITER

Updated the code to remove the DELIMITER

#DELIMITER USED TO BE HERE
CREATE DEFINER=CURRENT_USER FUNCTION `uuid_from_bin`(b BINARY(16)) RETURNS char(36) CHARSET latin1
    DETERMINISTIC
BEGIN
  DECLARE hex CHAR(32);
  SET hex = HEX(b);
  RETURN LOWER(CONCAT(LEFT(hex, 8), '-', MID(hex, 9,4), '-', MID(hex, 13,4), '-', MID(hex, 17,4), '-', RIGHT(hex, 12)));
RETURN 1;
END;
like image 589
CLo Avatar asked Sep 24 '14 18:09

CLo


People also ask

Does PDO work with MySQL?

PDO will work on 12 different database systems, whereas MySQLi will only work with MySQL databases. So, if you have to switch your project to use another database, PDO makes the process easy. You only have to change the connection string and a few queries.

How do you connect to a MySQL database using PDO?

A PDO database connection requires you to create a new PDO object with a Data Source Name (DSN), Username, and Password. The DSN defines the type of database, the name of the database, and any other information related to the database if required. These are the variables and values we stated inside the dbconfig.

What is the difference between using MySQL functions and PDO?

MySQLi is a replacement for the mysql functions, with object-oriented and procedural versions. It has support for prepared statements. PDO (PHP Data Objects) is a general database abstraction layer with support for MySQL among many other databases.

Is PHP PDO deprecated?

PHP 8.1: PDO::FETCH_SERIALIZE is deprecated This functionality, however, is broken and is unusable.


1 Answers

You don't need to use DELIMITER when you submit a statement through an API like PDO.

In fact, you must not use DELIMITER, because it's not recognized by the server's SQL parser. It's only recognized in the mysql client.

like image 185
Bill Karwin Avatar answered Sep 21 '22 14:09

Bill Karwin