Added error handling for LOB types as output parameters
This commit is contained in:
parent
9bbc673023
commit
e5a3767089
|
@ -417,6 +417,10 @@ pdo_error PDO_ERRORS[] = {
|
||||||
PDO_SQLSRV_ERROR_CE_EMULATE_PREPARE_UNSUPPORTED,
|
PDO_SQLSRV_ERROR_CE_EMULATE_PREPARE_UNSUPPORTED,
|
||||||
{ IMSSP, (SQLCHAR*) "Parameterized statement with attribute PDO::ATTR_EMULATE_PREPARES is not supported in a Column Encryption enabled Connection.", -82, false }
|
{ IMSSP, (SQLCHAR*) "Parameterized statement with attribute PDO::ATTR_EMULATE_PREPARES is not supported in a Column Encryption enabled Connection.", -82, false }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED,
|
||||||
|
{ IMSSP, (SQLCHAR*) "Stored Procedures do not support text, ntext or image as OUTPUT parameters.", -83, false }
|
||||||
|
},
|
||||||
{ UINT_MAX, {} }
|
{ UINT_MAX, {} }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1689,6 +1689,7 @@ enum SQLSRV_ERROR_CODES {
|
||||||
SQLSRV_ERROR_KEYSTORE_PATH_MISSING,
|
SQLSRV_ERROR_KEYSTORE_PATH_MISSING,
|
||||||
SQLSRV_ERROR_KEYSTORE_KEY_MISSING,
|
SQLSRV_ERROR_KEYSTORE_KEY_MISSING,
|
||||||
SQLSRV_ERROR_KEYSTORE_INVALID_VALUE,
|
SQLSRV_ERROR_KEYSTORE_INVALID_VALUE,
|
||||||
|
SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED,
|
||||||
|
|
||||||
// Driver specific error codes starts from here.
|
// Driver specific error codes starts from here.
|
||||||
SQLSRV_ERROR_DRIVER_SPECIFIC = 1000,
|
SQLSRV_ERROR_DRIVER_SPECIFIC = 1000,
|
||||||
|
|
|
@ -422,6 +422,12 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
|
||||||
|
|
||||||
// if it's an output parameter and the user asks for a certain type, we have to convert the zval to that type so
|
// if it's an output parameter and the user asks for a certain type, we have to convert the zval to that type so
|
||||||
// when the buffer is filled, the type is correct
|
// when the buffer is filled, the type is correct
|
||||||
|
CHECK_CUSTOM_ERROR( direction != SQL_PARAM_INPUT && (sql_type == SQL_LONGVARCHAR
|
||||||
|
|| sql_type == SQL_WLONGVARCHAR || sql_type == SQL_LONGVARBINARY),
|
||||||
|
stmt, SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED ){
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
|
||||||
if( direction == SQL_PARAM_OUTPUT ){
|
if( direction == SQL_PARAM_OUTPUT ){
|
||||||
switch( php_out_type ) {
|
switch( php_out_type ) {
|
||||||
case SQLSRV_PHPTYPE_INT:
|
case SQLSRV_PHPTYPE_INT:
|
||||||
|
|
|
@ -408,6 +408,11 @@ ss_error SS_ERRORS[] = {
|
||||||
SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND,
|
SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND,
|
||||||
{ IMSSP, (SQLCHAR*) "The specified ODBC Driver is not found.", -107, false }
|
{ IMSSP, (SQLCHAR*) "The specified ODBC Driver is not found.", -107, false }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED,
|
||||||
|
{ IMSSP, (SQLCHAR*) "Stored Procedures do not support text, ntext or image as OUTPUT parameters.", -108, false }
|
||||||
|
},
|
||||||
|
|
||||||
// terminate the list of errors/warnings
|
// terminate the list of errors/warnings
|
||||||
{ UINT_MAX, {} }
|
{ UINT_MAX, {} }
|
||||||
};
|
};
|
||||||
|
|
133
test/functional/sqlsrv/srv_231_string_truncation_text.phpt
Normal file
133
test/functional/sqlsrv/srv_231_string_truncation_text.phpt
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
--TEST--
|
||||||
|
GitHub issue #231 - String truncation when binding text/ntext/image to check error messages
|
||||||
|
--ENV--
|
||||||
|
PHPT_EXEC=true
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require('skipif_versions_old.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
sqlsrv_configure('WarningsReturnAsErrors', 1);
|
||||||
|
|
||||||
|
require_once("MsCommon.inc");
|
||||||
|
|
||||||
|
// connect
|
||||||
|
$conn = AE\connect();
|
||||||
|
if (!$conn) {
|
||||||
|
fatalError("Connection could not be established.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$tableName = 'testLOBTypes_GH231';
|
||||||
|
$columnNames = array("c1", "c2");
|
||||||
|
|
||||||
|
for ($k = 1; $k <= 3; $k++) {
|
||||||
|
$sqlType = sqlType($k);
|
||||||
|
$columns = array(new AE\ColumnMeta('int', $columnNames[0]),
|
||||||
|
new AE\ColumnMeta($sqlType, $columnNames[1]));
|
||||||
|
AE\createTable($conn, $tableName, $columns);
|
||||||
|
|
||||||
|
$sql = "INSERT INTO [$tableName] ($columnNames[0], $columnNames[1]) VALUES (?, ?)";
|
||||||
|
$data = getData($k);
|
||||||
|
|
||||||
|
$phpType = SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR);
|
||||||
|
$sqlsrvSQLType = sqlsrvSqlType($k, strlen($data));
|
||||||
|
|
||||||
|
$params = array($k, array($data, SQLSRV_PARAM_IN, $phpType, $sqlsrvSQLType));
|
||||||
|
$stmt = sqlsrv_prepare($conn, $sql, $params);
|
||||||
|
sqlsrv_execute($stmt);
|
||||||
|
sqlsrv_free_stmt($stmt);
|
||||||
|
|
||||||
|
execProc($conn, $tableName, $columnNames, $k, $data, $sqlType);
|
||||||
|
|
||||||
|
dropTable($conn, $tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_close($conn);
|
||||||
|
|
||||||
|
|
||||||
|
function execProc($conn, $tableName, $columnNames, $k, $data, $sqlType)
|
||||||
|
{
|
||||||
|
$spArgs = "@p1 int, @p2 $sqlType OUTPUT";
|
||||||
|
$spCode = "SET @p2 = ( SELECT c2 FROM $tableName WHERE c1 = @p1 )";
|
||||||
|
$procName = "testBindOutSp";
|
||||||
|
|
||||||
|
$stmt1 = sqlsrv_query($conn, "CREATE PROC [$procName] ($spArgs) AS BEGIN $spCode END");
|
||||||
|
sqlsrv_free_stmt($stmt1);
|
||||||
|
|
||||||
|
echo "\nData Type: ".$sqlType." binding as \n";
|
||||||
|
|
||||||
|
$direction = SQLSRV_PARAM_OUT;
|
||||||
|
echo "Output parameter: ";
|
||||||
|
invokeProc($conn, $procName, $k, $direction, $data);
|
||||||
|
|
||||||
|
$direction = SQLSRV_PARAM_INOUT;
|
||||||
|
echo "InOut parameter: ";
|
||||||
|
invokeProc($conn, $procName, $k, $direction, $data);
|
||||||
|
|
||||||
|
dropProc($conn, $procName);
|
||||||
|
}
|
||||||
|
|
||||||
|
function invokeProc($conn, $procName, $k, $direction, $data)
|
||||||
|
{
|
||||||
|
$sqlsrvSQLType = sqlsrvSqlType($k, strlen($data));
|
||||||
|
$callArgs = "?, ?";
|
||||||
|
|
||||||
|
// Data to initialize $callResult variable
|
||||||
|
$initData = "ShortString";
|
||||||
|
$callResult = $initData;
|
||||||
|
|
||||||
|
// Make sure not to specify the PHP type
|
||||||
|
$intType = AE\isColEncrypted()? SQLSRV_SQLTYPE_INT : null;
|
||||||
|
$params = array( array( $k, SQLSRV_PARAM_IN, null, $intType ),
|
||||||
|
array( &$callResult, $direction, null, $sqlsrvSQLType ));
|
||||||
|
$stmt = sqlsrv_query($conn, "{ CALL [$procName] ($callArgs)}", $params);
|
||||||
|
if ($stmt) {
|
||||||
|
fatalError("Expect this to fail!");
|
||||||
|
} else {
|
||||||
|
echo (sqlsrv_errors()[0]['message']) . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getData($k)
|
||||||
|
{
|
||||||
|
$data = "LongStringForTesting";
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sqlType($k)
|
||||||
|
{
|
||||||
|
switch ($k) {
|
||||||
|
case 1: return ("text");
|
||||||
|
case 2: return ("ntext");
|
||||||
|
case 3: return ("image");
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return ("udt");
|
||||||
|
}
|
||||||
|
|
||||||
|
function sqlsrvSqlType($k, $dataSize)
|
||||||
|
{
|
||||||
|
switch ($k) {
|
||||||
|
case 1: return (SQLSRV_SQLTYPE_TEXT);
|
||||||
|
case 2: return (SQLSRV_SQLTYPE_NTEXT);
|
||||||
|
case 3: return (SQLSRV_SQLTYPE_IMAGE);
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return (SQLSRV_SQLTYPE_UDT);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
--EXPECT--
|
||||||
|
|
||||||
|
Data Type: text binding as
|
||||||
|
Output parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters.
|
||||||
|
InOut parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters.
|
||||||
|
|
||||||
|
Data Type: ntext binding as
|
||||||
|
Output parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters.
|
||||||
|
InOut parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters.
|
||||||
|
|
||||||
|
Data Type: image binding as
|
||||||
|
Output parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters.
|
||||||
|
InOut parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters.
|
Loading…
Reference in a new issue