Stev
Stev

Reputation: 1112

PDO dblib not catching warnings

I have successfully made my symfony app connect to a MSSQL database using realestateconz/mssql-bundle and Free TDS.

My problem is that when I try to execute a stored procedure, that procedure throws an exception if something goes wrong, but PDO reports nothing back.

If I do the same thing using mssql_* functions I get a warning with the correct error message from MSSQL.

What is PDO doing differently?

Here are the two samples of code;

 //PDO Version
 try {
    $conn = new PDO($dsn, $user, $pass);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 } catch (PDOException $e) {
     var_dump($e->getMessage());
     die;
 }

 $stmt = $conn->prepare("INSERT INTO importex_parteneri (id_importex,  cif_cnp, denumire) VALUES (1, 9671891, 'Nexus Media')");
 $result = $stmt->execute();
 var_dump($result); //true

 $stmt = $conn->prepare("exec dbo.importex_parteneri_exec 1");
 $result = $stmt->execute();
 var_dump($result); //true

The mssql_* example

$connection = mssql_connect($server, $user , $pass);
mssql_select_db($nexus_bazadate, $connection);

$result = mssql_query("INSERT INTO importex_parteneri (id_importex, cif_cnp, denumire) VALUES (1, 9671891, 'Nexus Media')");
var_dump($result);

$result = mssql_query("exec dbo.importex_parteneri_exec 1");
var_dump($result);

/*
 * The output is
 * 
 * bool(true)
PHP Warning:  mssql_query(): message: Error 50000, Level 16, State 1, Procedure importex_parteneri_exec, Line 181, Message: PRT012 - Eroare import par9671891 (severity 16) in /home/vagrant/cv.dev/web/test.php on line 19
PHP Warning:  mssql_query(): General SQL Server error: Check messages from the SQL Server (severity 16) in /home/vagrant/cv.dev/web/test.php on line 19
bool(true)
 */
SOLUTION

I ended up adding a wraper around PDO::execute function function

execute(\PDOStatement $stmt, array $params = array())
{
    $result = $stmt->execute($params);

    $err = $stmt->errorInfo();
    switch ($err[0]) {
        case '00000':
        case '01000':
            return true;
        default:
            //case HY000
            return false;
    }
}

Upvotes: 2

Views: 796

Answers (1)

Álvaro González
Álvaro González

Reputation: 146490

I may be wrong but I don't recall seeing a native way to handle SQL warnings in PDO in a somehow automated way. According to a user comment you can test manually for the SQLSTATE error code and it'll be:

  • '00000' (success)
  • '01000' (success with warning)

If it actually works, it's of course annoying to do by hand. If you have a custom layer on top of PDO you can always do it in your custom exec method.

Upvotes: 2

Related Questions