diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 30fe36bb..bad0e38d 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -1856,16 +1856,16 @@ SQLSMALLINT default_c_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, break; case IS_TRUE: case IS_FALSE: - sql_c_type = SQL_C_SLONG; - break; + sql_c_type = SQL_C_SLONG; + break; case IS_LONG: - //ODBC 64-bit long and integer type are 4 byte values. - if ( ( Z_LVAL_P( param_z ) < INT_MIN ) || ( Z_LVAL_P( param_z ) > INT_MAX ) ) { - sql_c_type = SQL_C_SBIGINT; - } - else { - sql_c_type = SQL_C_SLONG; - } + //ODBC 64-bit long and integer type are 4 byte values. + if ((Z_LVAL_P(param_z) < INT_MIN) || (Z_LVAL_P(param_z) > INT_MAX)) { + sql_c_type = SQL_C_SBIGINT; + } + else { + sql_c_type = SQL_C_SLONG; + } break; case IS_DOUBLE: sql_c_type = SQL_C_DOUBLE; @@ -1929,13 +1929,13 @@ void default_sql_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ sql_type = SQL_INTEGER; break; case IS_LONG: - //ODBC 64-bit long and integer type are 4 byte values. - if ( ( Z_LVAL_P( param_z ) < INT_MIN ) || ( Z_LVAL_P( param_z ) > INT_MAX ) ) { - sql_type = SQL_BIGINT; - } - else { - sql_type = SQL_INTEGER; - } + //ODBC 64-bit long and integer type are 4 byte values. + if ((Z_LVAL_P(param_z) < INT_MIN) || (Z_LVAL_P(param_z) > INT_MAX)) { + sql_type = SQL_BIGINT; + } + else { + sql_type = SQL_INTEGER; + } break; case IS_DOUBLE: sql_type = SQL_FLOAT; diff --git a/test/functional/pdo_sqlsrv/pdo_ae_output_param_decimals.phpt b/test/functional/pdo_sqlsrv/pdo_ae_output_param_decimals.phpt index 339c6821..e1fd26cb 100644 --- a/test/functional/pdo_sqlsrv/pdo_ae_output_param_decimals.phpt +++ b/test/functional/pdo_sqlsrv/pdo_ae_output_param_decimals.phpt @@ -133,12 +133,14 @@ function testOutputDecimals($inout) // call stored procedure $outSql = getCallProcSqlPlaceholders($spname, 2); foreach ($pdoParamTypes as $pdoParamType) { - $det = $rand = 0.0; + // Do not initialize $det or $rand as empty strings + // See VSO 2915 for details. The string must be a numeric + // string, and to make it work for all precisions, we + // simply set it to a single-digit string. + $det = $rand = '0'; $stmt = $conn->prepare($outSql); $len = 2048; - // Do not initialize $det or $rand as empty strings - // See VSO 2915 for details if ($pdoParamType == PDO::PARAM_BOOL || $pdoParamType == PDO::PARAM_INT) { $len = PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE; $det = $rand = 0; diff --git a/test/functional/sqlsrv/srv_699_out_param_integer.phpt b/test/functional/sqlsrv/srv_699_out_param_integer.phpt new file mode 100644 index 00000000..39f19569 --- /dev/null +++ b/test/functional/sqlsrv/srv_699_out_param_integer.phpt @@ -0,0 +1,94 @@ +--TEST-- +GitHub issue #699 - binding integer as output parameter failed +--DESCRIPTION-- +This test uses the sample stored procedure provided by the user, in which an +error situation caused the binding to fail with an irrelevant error message about UTF-8 translation. This test proves that this issue has been fixed. +--ENV-- +PHPT_EXEC=true +--SKIPIF-- + +--FILE-- + "UTF-8", "ConnectionPooling"=>1); +$conn = connect($connectionOptions); + +$tableName1 = "table_issue699_1"; +$tableName2 = "table_issue699_2"; +$procName = "proc_issue699"; + +dropTable($conn, $tableName1); +dropTable($conn, $tableName2); +dropProc($conn, $procName); + +// Create two test tables without encryption +$sql = "CREATE TABLE $tableName1 (correio_electronico NVARCHAR(50), nome NVARCHAR(50), telefones NVARCHAR(15), id_entidade INT)"; +$stmt = sqlsrv_query($conn, $sql); +if (!$stmt) { + fatalError("Failed to create table $tableName1\n"); +} + +$sql = "CREATE TABLE $tableName2 (estado TINYINT NOT NULL DEFAULT 0)"; +$stmt = sqlsrv_query($conn, $sql); +if (!$stmt) { + fatalError("Failed to create table $tableName2\n"); +} + +// Create the stored procedure +$sql = "CREATE PROCEDURE $procName @outparam INT OUTPUT AS + BEGIN + SET @outparam = 100; + INSERT INTO $tableName1 (correio_electronico, nome, telefones, id_entidade) + SELECT 'membros@membros.pt', 'Teste', 'xxx', 1 + FROM $tableName2 CC + WHERE CC.estado = 100 + BEGIN TRY + SET @outparam = 123 + END TRY + BEGIN CATCH + END CATCH + END"; + +$stmt = sqlsrv_query($conn, $sql); +if (!$stmt) { + fatalError("Error in creating the stored procedure $procName\n"); +} + +$set_no_count = ""; +if (strtoupper(substr(PHP_OS, 0, 3)) === 'LIN') { + // This test, when running outside of Windows, requires unixODBC 2.3.4 + // or above (see the list of bug fixes in www.unixodbc.org) + // Add this workaround for Linux platforms + $set_no_count = "SET NOCOUNT ON; "; +} + +$sql_callSP = $set_no_count . "{call $procName(?)}"; + +// Initialize the output parameter to any number +$outParam = 1; +$params = array(array(&$outParam, SQLSRV_PARAM_OUT)); +$stmt = sqlsrv_query($conn, $sql_callSP, $params); +if (!$stmt) { + fatalError("Error in calling $procName\n"); +} + +while ($res = sqlsrv_next_result($stmt)); + +if ($outParam != 123) { + echo "The output param value $outParam is unexpected!\n"; +} + +dropTable($conn, $tableName1); +dropTable($conn, $tableName2); +dropProc($conn, $procName); + +// Free handles +sqlsrv_free_stmt($stmt); +sqlsrv_close($conn); + +echo "Done\n"; + +?> +--EXPECT-- +Done \ No newline at end of file