added error handling for emulate prepared statement with inout parameters
This commit is contained in:
parent
fa38f7d61c
commit
2aec3b4a95
|
@ -1115,6 +1115,10 @@ int pdo_sqlsrv_stmt_param_hook(pdo_stmt_t *stmt,
|
||||||
|
|
||||||
// since the param isn't reliable, we don't do anything here
|
// since the param isn't reliable, we don't do anything here
|
||||||
case PDO_PARAM_EVT_ALLOC:
|
case PDO_PARAM_EVT_ALLOC:
|
||||||
|
if ( stmt->supports_placeholders == PDO_PLACEHOLDER_NONE && (param->param_type & PDO_PARAM_INPUT_OUTPUT )) {
|
||||||
|
sqlsrv_stmt* driver_stmt = reinterpret_cast<sqlsrv_stmt*>( stmt->driver_data );
|
||||||
|
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_EMULATE_INOUT_UNSUPPORTED );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PDO_PARAM_EVT_FREE:
|
case PDO_PARAM_EVT_FREE:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -373,6 +373,10 @@ pdo_error PDO_ERRORS[] = {
|
||||||
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED,
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED,
|
||||||
{ IMSSP, (SQLCHAR*) "Memory limit of %1!d! KB exceeded for buffered query", -71, true }
|
{ IMSSP, (SQLCHAR*) "Memory limit of %1!d! KB exceeded for buffered query", -71, true }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
PDO_SQLSRV_ERROR_EMULATE_INOUT_UNSUPPORTED,
|
||||||
|
{ IMSSP, (SQLCHAR*) "Statement with emulate prepare on does not support output or input_output parameters.", -72, false }
|
||||||
|
},
|
||||||
{ UINT_MAX, {} }
|
{ UINT_MAX, {} }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -389,7 +389,7 @@ enum PDO_ERROR_CODES {
|
||||||
PDO_SQLSRV_ERROR_INVALID_COLUMN_INDEX,
|
PDO_SQLSRV_ERROR_INVALID_COLUMN_INDEX,
|
||||||
PDO_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE,
|
PDO_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE,
|
||||||
PDO_SQLSRV_ERROR_INVALID_CURSOR_WITH_SCROLL_TYPE,
|
PDO_SQLSRV_ERROR_INVALID_CURSOR_WITH_SCROLL_TYPE,
|
||||||
|
PDO_SQLSRV_ERROR_EMULATE_INOUT_UNSUPPORTED,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern pdo_error PDO_ERRORS[];
|
extern pdo_error PDO_ERRORS[];
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
--TEST--
|
||||||
|
uses an input/output parameter with emulate prepare
|
||||||
|
--SKIPIF--
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require_once("autonomous_setup.php");
|
||||||
|
$database = 'tempdb';
|
||||||
|
$dsn = "sqlsrv:Server=$serverName ; Database = $database";
|
||||||
|
try {
|
||||||
|
$dbh = new PDO($dsn, $username, $password);
|
||||||
|
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
|
$dbh->query("IF OBJECT_ID('sp_ReverseString', 'P') IS NOT NULL DROP PROCEDURE sp_ReverseString");
|
||||||
|
$dbh->query("CREATE PROCEDURE sp_ReverseString @String as VARCHAR(2048) OUTPUT as SELECT @String = REVERSE(@String)");
|
||||||
|
$stmt = $dbh->prepare("EXEC sp_ReverseString ?", array(PDO::ATTR_EMULATE_PREPARES => true));
|
||||||
|
$string = "123456789";
|
||||||
|
$stmt->bindParam(1, $string, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 2048);
|
||||||
|
$stmt->execute();
|
||||||
|
print "Result: ".$string;
|
||||||
|
|
||||||
|
//free the statement and connection
|
||||||
|
$stmt = null;
|
||||||
|
$dbh = null;
|
||||||
|
}
|
||||||
|
catch(PDOException $e) {
|
||||||
|
print("Error: " . $e->getMessage() . "\n");
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Error: SQLSTATE[IMSSP]: Statement with emulate prepare on does not support output or input_output parameters.
|
|
@ -0,0 +1,82 @@
|
||||||
|
--TEST--
|
||||||
|
Test emulate prepare with mix bound param encodings and positional placeholders (i.e., using '?' as placeholders)
|
||||||
|
--SKIPIF--
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require_once("autonomous_setup.php");
|
||||||
|
|
||||||
|
$connection_options['pdo'] = array();
|
||||||
|
$connection_options['pdo'][PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
|
||||||
|
|
||||||
|
$database = "tempdb";
|
||||||
|
$cnn = new PDO("sqlsrv:Server=$serverName;Database=$database", $username, $password, $connection_options['pdo']);
|
||||||
|
|
||||||
|
// Drop
|
||||||
|
try {
|
||||||
|
$pdo_options = array();
|
||||||
|
$pdo_options[PDO::ATTR_EMULATE_PREPARES] = TRUE;
|
||||||
|
$pdo_options[PDO::SQLSRV_ATTR_DIRECT_QUERY] = TRUE;
|
||||||
|
$pdo_options[PDO::ATTR_CURSOR] = PDO::CURSOR_SCROLL;
|
||||||
|
$pdo_options[PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE] = PDO::SQLSRV_CURSOR_BUFFERED;
|
||||||
|
$st = $cnn->prepare('DROP TABLE WATCHDOG', $pdo_options);
|
||||||
|
|
||||||
|
$st->execute();
|
||||||
|
}
|
||||||
|
catch(\Exception $e) {}
|
||||||
|
|
||||||
|
$tablescript = <<<EOF
|
||||||
|
CREATE TABLE [dbo].[watchdog](
|
||||||
|
[system_encoding] [nvarchar](128),
|
||||||
|
[utf8_encoding] [nvarchar](128),
|
||||||
|
[binary_encoding] [varbinary](max))
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
// Recreate
|
||||||
|
$st = $cnn->prepare($tablescript, $pdo_options);
|
||||||
|
$st->execute();
|
||||||
|
|
||||||
|
$query = <<<EOF
|
||||||
|
INSERT INTO [watchdog] ([system_encoding], [utf8_encoding], [binary_encoding]) VALUES
|
||||||
|
(?, ?, ?)
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
/** @var MyStatement */
|
||||||
|
$st = $cnn->prepare($query, $pdo_options);
|
||||||
|
|
||||||
|
$system_param = 'system encoded string';
|
||||||
|
$utf8_param = '가각ácasa';
|
||||||
|
$binary_param = fopen('php://memory', 'a');
|
||||||
|
fwrite($binary_param, 'asdgasdgasdgsadg');
|
||||||
|
rewind($binary_param);
|
||||||
|
|
||||||
|
$st->bindParam(1, $system_param, PDO::PARAM_STR);
|
||||||
|
$st->bindParam(2, $utf8_param, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_UTF8);
|
||||||
|
$st->bindParam(3, $binary_param, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
|
||||||
|
|
||||||
|
$st->execute();
|
||||||
|
|
||||||
|
$st = $cnn->query("SELECT * FROM [watchdog]");
|
||||||
|
var_dump($st->fetchAll());
|
||||||
|
|
||||||
|
$st = NULL;
|
||||||
|
$cnn = NULL;
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(6) {
|
||||||
|
["system_encoding"]=>
|
||||||
|
string(21) "system encoded string"
|
||||||
|
[0]=>
|
||||||
|
string(21) "system encoded string"
|
||||||
|
["utf8_encoding"]=>
|
||||||
|
string(12) "가각ácasa"
|
||||||
|
[1]=>
|
||||||
|
string(12) "가각ácasa"
|
||||||
|
["binary_encoding"]=>
|
||||||
|
string(16) "asdgasdgasdgsadg"
|
||||||
|
[2]=>
|
||||||
|
string(16) "asdgasdgasdgsadg"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue