简体   繁体   中英

PHP 5.5's (MS) SQL server functions not working as expected

My sys admin is upgrading my PHP server from 5.2 to 5.5 . As a result, the mssql family of functions is gone and I have to update my code (it seems to either the odbc functions or sqlsrv functions). Unfortunately, neither seems to be working correctly for anything beyond simple queries.

I've reduced one of the problematic queries down to the following two variants (middle line added is the only change):

IF OBJECT_ID('tempdb..#i') IS NOT NULL BEGIN DROP TABLE #i END
SELECT 'value' as test

IF OBJECT_ID('tempdb..#i') IS NOT NULL BEGIN DROP TABLE #i END
CREATE TABLE #i (id INT primary key) INSERT INTO #i SELECT 405782
SELECT 'value' as test

When I try them in SQL Server Mangement Studio, both work fine and return one row. When I try the first one from PHP, it works fine and returns one row. However, when I try to execute the second query from PHP I get an unexpected result:

$SQL_query= '********'; //Second query
$serverName = '**********';
$connectionInfo = array( "Database"=>"*****","UID"=>"********","PWD"=>"*********");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
$msg1=sqlsrv_errors(SQLSRV_ERR_ALL); // ""

if($conn){ //truthy
  $result=sqlsrv_query($conn,$SQL_query);
  if(sqlsrv_has_rows ($result)){$rows='true';}else{$rows='false';} //false
  $msg2=sqlsrv_errors(SQLSRV_ERR_ALL); // ""
  $row=sqlsrv_fetch_array($result,SQLSRV_FETCH_NUMERIC) //false
}

(The odbc functions were even worse, choking if the query contained a SET @var statement...)

So the result of the query is incorrect, but no errors are reported.

Can anyone explain this? You'd think if the range of queries that could be handled by these functions was somehow limited that it would be at least mentioned in passing in the PHP documentation for these functions.

For reference: Microsoft SQL Server Standard Edition 9.00.1406.00, PHP 5.5.19 x86 thread safety disabled, running on Windows.

Edit: Per Rob Farley's suggestion, I've confirmed that the @@OPTIONS are either identical or immaterial to reproducing the problem.

Depending on what driver you're using (freetds?), you could be finding that ANSI_NULLS (and other ANSI settings, such as QUOTED_IDENTIFIER ) are set differently to what is expected, and this can affect things such as the creation of tables. Try passing in a query that tests those values, and you will quite probably find the problem.

The problem is that the client framework is confused by the row counts that are returned by default for every statement. When the first INSERT happens, it returns a row count of 1, making it appear as if this is a statement returning results, which it's not -- the row count may even get confused for the result itself. PHP isn't the only technology troubled by this; jTDS is another driver that has trouble (in the case of jTDS, it requires the row count). SET NOCOUNT ON suppresses this extra information:

SET NOCOUNT ON
IF OBJECT_ID('tempdb..#i') IS NOT NULL BEGIN DROP TABLE #i END
CREATE TABLE #i (id INT primary key)
INSERT INTO #i SELECT 405782
SELECT 'value' as test

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM