0
votes

I'm using PDO with ODBC from PHP7.4 to SQLServer 12 with this Connection String:

$conn = new PDO('odbc:DRIVER={SQL Server};SERVER=MyServer,1433;Database=MyDatabase;', 'MyUser', 'MyPass');

A regular query with an Integer parameter returns data:

$SQL = <<<EOL
Select
    [10-Digit Groups].[Area Code],
    [10-Digit Groups].[Group]
From
    [10-Digit Groups]
Where
    [10-Digit Groups].[Area Code] = ?
EOL;

    $stmt = $conn->prepare($SQL);
    $ac1 = 602;
    $success = $stmt->bindParam(1, $ac1);
    $success = $stmt->execute();
    foreach($stmt as $row){
        var_dump($row);
    }

So I add a subquery (Ctr1):

    $SQL = <<<EOL
Select
    [10-Digit Groups].[Area Code],
    (Select Count(*) From [10-Digit Groups]) Ctr1,
    [10-Digit Groups].[Group]
From
    [10-Digit Groups]
Where
    [10-Digit Groups].[Area Code] = ?

EOL;

    $stmt = $conn->prepare($SQL);
    $ac1 = 602;
    $success = $stmt->bindParam(1, $ac1);
    $success = $stmt->execute();
    foreach($stmt as $row){
        var_dump($row);
    }

And it fails with:

//Uncaught PDOException: SQLSTATE[22018]: Invalid character value for cast specification: 206 [Microsoft][ODBC SQL Server Driver][SQL Server]Operand type clash: text is incompatible with int (SQLExecute[206] at ext\pdo_odbc\odbc_stmt.c:259)

I can perform similar queries with STRING parameters, but they fail with this error:

//Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 402 [Microsoft][ODBC SQL Server Driver][SQL Server]The data types nvarchar and text are incompatible in the equal to operator. (SQLExecute[402] at ext\pdo_odbc\odbc_stmt.c:259)

I've tried setting and unsetting these:

$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

And I've tried setting the DataType in PDO:

$success = $stmt->bindParam(1, $a1, PDO::PARAM_STR); //Or PDO::PARAM_INT where appropriate

I've also hard-coded the parameter values into the SQL to ensure they work.

I've also tried passing the parameters in the 'execute' statement:

PDO->execute([602])

I've also tried converting both sides of the WHERE clause to nvarchar or int.

Everything works as normal with no subquery, but once it's there, the Prepared Statement fails.

Any suggestions to try (Driver String, Subquery Nesting Strategies, other PDO Attribute adjustments, etc.)?

1

1 Answers

0
votes

I fixed this with 2 actions:

Install "ODBC Driver 11 for SQL Server" from Microsoft (search for it)

And change DRIVER={SQL Server}; to DRIVER={ODBC Driver 11 for SQL Server};

It caused a couple of rewrites, but for the most part was a direct replacement. It allows for multiple parameters alongside subqueries. All examples above work fine with this change.

P.S. This change also works for non-PDO odbc commands in PHP.