workaround for unixODBC bug returning error when pdo::exec query with empty result set

This commit is contained in:
v-kaywon 2017-03-27 17:49:01 -07:00
parent 6809f0f7ea
commit 7256685a4c
2 changed files with 64 additions and 0 deletions

View file

@ -2040,6 +2040,17 @@ namespace core {
SQLRETURN r;
SQLSMALLINT num_cols;
r = ::SQLNumResultCols( stmt->handle(), &num_cols );
// Workaround for a bug in unixODBC: after SQLExecDirect for an empty result set,
// r = ::SQLNumResultCols( stmt->handle(), &num_cols );
// returns r=-1 (SQL_ERROR) and error HY010 (Function sequence error)
// but it should have succeeded with r=0 (SQL_SUCCESS) and no error
// instead of throwing an exception, return 0 if the r=-1, stament has been executed, and has a HY010 error
// (HY010 error should not return if stmt->execute is true)
#ifndef _WIN32
if ( r == -1 && stmt->execute && strcmp( reinterpret_cast<const char*>( stmt->last_error()->sqlstate ), "HY010" ) == 0 )
return 0;
#endif // !_WIN32
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw CoreException();

View file

@ -0,0 +1,53 @@
--TEST--
GitHub issue #336 - PDO::exec should not return an error with query returning SQL_NO_DATA
--DESCRIPTION--
Verifies GitHub issue 336 is fixed, PDO::exec on query returning SQL_NO_DATA will not give an error
--SKIPIF--
--FILE--
<?php
require_once("pdo_tools.inc");
// Connect
require_once("autonomous_setup.php");
$dbName = "tempdb";
$conn = new PDO("sqlsrv:server=$serverName;Database=$dbName", $username, $password);
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql = "DELETE FROM foo_table WHERE id = 42";
$sqlWithParameter = "DELETE FROM foo_table WHERE id = :id";
$sqlParameter = 42;
$Statement = $conn->exec("IF OBJECT_ID('foo_table', 'U') IS NOT NULL DROP TABLE foo_table");
$Statement = $conn->exec("CREATE TABLE foo_table (id BIGINT PRIMARY KEY NOT NULL IDENTITY, intField INT NOT NULL)");
$Statement = $conn->exec("INSERT INTO foo_table (intField) VALUES(3)");
//test prepare, not args
$stmt = $conn->prepare($sql);
$stmt->execute();
if ($conn->errorCode() == 00000)
echo "prepare OK\n";
//test prepare, with args
$stmt = $conn->prepare($sqlWithParameter);
$stmt->execute(array(':id' => $sqlParameter));
if ($conn->errorCode() == 00000)
echo "prepare with args OK\n";
//test direct exec
$stmt = $conn->exec($sql);
if ($conn->errorCode() == 00000)
echo "direct exec OK\n";
$Statement = $conn->exec("IF OBJECT_ID('foo_table', 'U') IS NOT NULL DROP TABLE foo_table");
$stmt = NULL;
$Statement = NULL;
$conn = NULL;
?>
--EXPECT--
prepare OK
prepare with args OK
direct exec OK