MSSQL vs. SQLSRV: What’s the Difference? (Part 2)
In my last post, I promised a comparison of the APIs for the MSSQL and SQLSRV extensions of PHP, so here it is. I constructed the table below assuming some familiarity with the MSSQL extension. I’m aiming to provide a high-level comparison that you might use if you were considering moving to the SQLSRV extension, but I think there is also some interesting information if you are just curious about the differences. (For a detailed comparison, I will point you to the MSSQL API documentation and the SQLSRV API documentation.) In cases where a short note wasn’t enough (and there were several of these), I’ve provided relevant links to topics in the SQLSRV documentation.
As I constructed the table below, a few major differences between the APIs stood out for me. I think they are worth noting before looking at the function-to-function comparison:
- The sqlsrv API offers the sqlsrv_prepare and sqlsrv_execute functions for executing a query multiple times with different parameter values. This potentially has performance benefits when performing a query repeatedly in a loop. For one-off queries, the sqlsrv_query function is recommended. For more information, see Comparing Execution Functions. (Note that any place in the table below where I suggest sqlsrv_query can be used, the combination of sqlsrv_prepare/sqlsrv_execute could also be used.)
- The sqlsrv API has no special functions for executing stored procedures (in constrast to the mssql_init, mssql_bind, and mssql_execute functions in the mssql API). A stored procedure is executed by defining a SQL string like this:
$sql = "{call StoredProcedureName(?, ?)}";
The question marks are place holders for stored procedure parameters (if there are any). This query is then executed like any other query (with sqlsrv_query or sqlsrv_prepare/sqlsrv_execute). For more information and examples, see How to: Retrieve Output Parameters, How to: Retrieve Input/Output Parameters, and sqlsrv_next_result.
- The sqlsrv API has only one function for handling errors, sqlsrv_errors, which returns error information about the last sqlsrv operation that was performed. This is in contrast to the mssql_get_last_message, mssql_min_error_severity, and mssql_min_message_severity functions offered in the mssql API.
- While the mssql API offers the mssql_connect and mssql_pconnect functions for establishing connections and “persistent” connections respectively , the sqlsrv API relies on ODBC connection pooling to make sure the overhead of creating a new connection is kept to a minimum. Connection pooling is on by default. For more information, see Connection Pooling.
- The sqlsrv API uses scrollable cursors to allow random access to the rows of a result set. (For more information, see Specifying a Cursor Type and Selecting Rows.) The mssql API pulls an entire result set into memory to allow random access to the rows of a result set. Each of these implementations has benefits and drawbacks depending on the needs of your application. (Maybe a deep dive into this topic would be a good topic for another blog post...what do you think?)
If you have used both API’s (or if you’ve just read the comparison), I’d be interested in which API you like better and why. Do you think one is more elegant than the other? Is one more practical than the other? I think this could be an interesting discussion.
MSSQL and SQLSRV Function Comparison
MSSQL Function |
SQLSRV Equivalent Function(s) |
Notes |
With the sqlsrv API, stored procedure parameters are defined in an array that is passed to sqlsrv_query or sqlsrv_prepare. For more information and examples, see How to: Retrieve Output Parameters, How to: Retrieve Input/Output Parameters, and sqlsrv_next_result. | ||
These functions are equivalent, but note that calling sqlsrv_close returns a connection to a connection pool. For more information, see Connection Pooling. | ||
These functions are equivalent, but note that sqlsrv_connect attempts to use a pooled connection before it creates a new one. For more information, see Connection Pooling. | ||
or |
The sqlsrv API provides forward-only reading of result sets by default. However, in v1.1 of the driver, you can specify and retrieve any row of a result set with sqlsrv_fetch or sqlsrv_fetch_array. For more information, see Specifying a Cursor Type and Selecting Rows. | |
There are no special functions for executing stored procedures in the sqlsrv API. Stored procedures are executed with the sqlsrv_query function. For more information and examples, see How to: Retrieve Output Parameters, How to: Retrieve Input/Output Parameters, and sqlsrv_next_result. | ||
These functions are equivalent. | ||
The sqlsrv_fetch_array function returns a row with both numeric and associative indexes by default. You can retrieve only an associative array by using the SQLSRV_FETCH_ASSOC constant in the function call. | ||
No equivalent function. |
While the sqlsrv API does not have a function equivalent of mssql_fetch_batch, the number of rows in a result set can obtained using sqlsrv_num_rows. As you process rows, you can track the number of remaining rows. | |
These functions both return metadata about a result set, although they each return slightly different metadata. See mssql_fetch_field and for sqlsrv_field_metadata details. | ||
These functions are equivalent. | ||
These functions are equivalent, but note that the sqlsrv_fetch_array function returns an array with both numeric and associative indexes by default. You can retrieve only a numeric array by using the SQLSRV_FETCH_NUMERIC constant in the function call. | ||
No equivalent function. |
Note that for some field types, the maximum length is returned by the sqlsrv_field_metadata function. | |
In addition to other information, the field name is retuned by the sqlsrv_field_metadata function. | ||
No equivalent function. |
When using the sqlsrv_get_field function, fields must be accessed in order. The sqlsrv API does not provide a way to access fields randomly. | |
In addition to other information, the field name is retuned by the sqlsrv_field_metadata function. | ||
These functions are equivalent. | ||
These functions both free resources associated with a statement, but note that the sqlsrv_free_stmt does this for any statement (not only statements associated with stored procedures). | ||
These functions both return error information about the last operation performed, but the sqlsrv_errors function returns information in an array (error code and error message). | ||
No equivalent function. |
While the sqlsrv API does not provide a function for converting GUIDs to strings, you can convert GUIDS to string-compatible types on the server with the CONVERT function. | |
No equivalent function. |
There is no special function for initializing stored procedures in the sqlsrv API. Stored procedures are executed with the sqlsrv_query function. For more information and examples, see How to: Retrieve Output Parameters, How to: Retrieve Input/Output Parameters, and sqlsrv_next_result. | |
No equivalent function. |
The sqlsrv API does not provide functionality for filtering errors based on severity. For information on handling errors with the sqlsrv API, see How to: Configure Error and Warning Handling and How to: Handle Errors and Warnings. | |
No equivalent function. |
The sqlsrv API does not provide functionality for filtering errors based on severity. For information on handling errors with the sqlsrv API, see How to: Configure Error and Warning Handling and How to: Handle Errors and Warnings. | |
These functions are equivalent. | ||
These functions are equivalent. | ||
These functions are equivalent. | ||
The default behavior of the sqlsrv_connect function is to open a pooled connection if one is available. When a script ends or when sqlsrv_close is called, the connection is returned to the connection pool. For more information, see Connection Pooling. | ||
These functions are equivalent. | ||
The combination of the sqlsrv_fetch and sqlsrv_get_field functions are equivalent to the mssql_result function. Calling sqlsrv_fetch makes a row of data available for reading and sqlsrv_get_field reads fields in the current row. | ||
These functions are equivalent. | ||
No equivalent function. |
To select a database with the sqlsrv API, use sqlsrv_query to execute the following query: USE databaseName. |
That’s all for today folks…thanks!
-Brian
Comments
Anonymous
March 11, 2010
The comment has been removedAnonymous
March 11, 2010
The comment has been removedAnonymous
March 12, 2010
The comment has been removedAnonymous
April 26, 2010
Daniel-Hopefully this isn't too late too late to help you out: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=df4d9cc9-459c-4d75-a503-ae3fceb85860-BrianAnonymous
June 18, 2010
thankswww.freedownloadpond.comAnonymous
July 07, 2010
Hi Brian, I hope you can help me. I`m developing one project with sqlsrv but I have one problem when I want to run a stored procedure with OUTPUT parameter guid format. I have predefined format of const EMPTY_GUID = '00000000-0000-0000-0000-000000000000'; Everythin works fine, but retrieved GIUD from the database is broken with question mark in last character like "4C532F26-126E-4ADD-84F0-B7059E5E032?" I checked all setting in PHP, APACHE, MS SQL and everything seems fine. Charset, collation, everything is the same on all sides. DO you have any idea what could be wrong please? thank you!Anonymous
July 08, 2010
Milan-Without looking at your code, I can't really say what the problem might be. I think the best thing to do in this case is to start a thread in the forum (social.msdn.microsoft.com/.../threads) that includes the code that is causing the issue. (I'm assuming you are using the sqlsrv driver and not the mssql driver.) Once I can reproduce the problem, we can figure out how to fix it.Thanks.-BrianAnonymous
November 02, 2010
Brian,Thanks for the great summary of the APIs. I have a couple of suggestions for improvement. If you use to use: mssql_query followed by mssql_fetch_array, you can't just use sqlsrv_query and sqlsrv_fetch_array functions as they are not quite equivalent. The fetch will fail unless you change the Scrollable to static. The query also has different returns if there are zero rows. mssql returns a true instead of a resource.PaulAnonymous
November 03, 2010
Thanks, Paul. That looks like useful information that I should add to the post...I'll confirm and add it!Cheers,BrianAnonymous
November 04, 2010
Brian,What I said may have been incorrect. I mentioned the wrong function! It is num_rows, not fetch_array that caused the problem. Here is mssql code and how to rewrite it to work with sqlsrv when using num_rows:$res = mssql_query($sql, $conn);$num = mssql_num_rows($res);Should be rewritten as:$res = sqlsrv_query($conn, $sql, array(), array("Scrollable" => SQLSRV_CURSOR_STATIC));$num = sqlsrv_num_rows($res);PaulAnonymous
January 28, 2011
hello.thank for this article. meybe you forget to compare with mysql?Anonymous
January 31, 2011
@faca5 - You are right! I will right that post soon...thanks.Anonymous
February 08, 2011
The comment has been removedAnonymous
February 22, 2011
I have a problem when I run php.exePhp startup: sqlsrv: unable to initialize moduleModule compiled with module API=20060613PHP compiled with module API=20090626These options need to matchI usedPHP Version 5.3.1php.iniextension=php_sqlsrv_52_ts_vc6.dllextension=php_pdo_sqlsrv_52_ts_vc6.dllanyone who can help me to solve this problem?thanksAnonymous
February 22, 2011
Hello, Pure.I think I can help. Actually, the answer lies in the output of php.The binary versions need to match. Change your PHP.ini to:extension=php_sqlsrv_52_ts_vc9.dllextension=php_pdo_sqlsrv_52_ts_vc9.dllNotice VC9 instead of VC6.This should work.Anonymous
April 26, 2012
Just wanted to point out that mssql_num_rows and sqlsrv_num_rows are NOT equivalent. You cannot get the number of rows from a forward cursor (the default) when using sqlsrv_next_result. The two behaviors are not even close to the same. You may want to point that out. If you call a stored procedure with multiple result sets, plan on doing a lot of recoding.Anonymous
June 05, 2012
mssql_query and sqlsrv_query are not equivalent: the first needs just a single argument (T-SQL command) the latter needs the resource parameter and the T-SQL command (sqlsrv_query( resource $conn, string $tsql [, array $params [, array $options]])).Anonymous
June 13, 2013
Parabéns Brian pelo post.Gostaria de saber como faço para executar uma procedure usando sqlsrv no php.aguardo.Anonymous
May 12, 2015
This is a bit late, but one issue I've noticed is that I could use T-SQL variables with mssql, but I can't seem to with sqlsrv. This is a simplistic example, but the following used to work, but doesn't with sqlsrv: DECLARE @variable INT = 10 SELECT @variable variable_name Specifically, I have a number of examples in an application and would love to be able to port it over. Any suggestions would be very helpful. Thanks, NeilAnonymous
May 12, 2015
It turns out, I'm completely wrong. This seems to be absolutely fine.Anonymous
September 28, 2015
sqlsrv_num_rows no funciona cuando el $sql es un procedimiento almacenado