You can edit "charset" in php.ini too (but you don't need if you did it previously in freetds.conf):; Specify client character set..; If empty or not set the client charset from freetds.comf is used; This is only used when compiled with FreeTDSmssql.charset = "UTF-8"

Note that although the documentations states that mssql_query will return "TRUE if no rows were returned", it will still return an empty resource identifier for SELECT statements that do not return any rows. This empty resource identifier will get dynamically typed as TRUE in a boolean context. Only for queries that do not actually return rows (eg. insert, update, or delete) will mssql_query return an actual boolean TRUE value.

We should use mssql_num_rows($resource) rather than $resource===TRUE for checking whether rows were returned.

Regarding the problems mentioned on here with the format that datetime columns are returned in. Running on debian lenny and used apt-get install php5-sybase to get access to these functions. After which datetime fields were returned as a string something like 'Feb 16 2010 09:14:10:010AM' which was not recognised when passed to e.g. new DateTime(). Also smalldatetime fields caused php to crash.

To fix I did this:

vi /etc/php5/apache2/php.iniAfter this line:;mssql.datetimeconvert = OnAdd this line:mssql.datetimeconvert = Off

Now both datetime and smalldatetime come back as something like '2010-02-16 09:14:00'.

Here you might expect to see the last insert id, but you see nothing. This is because the resource is currently pointing to the 'true' from the first query (the insert query) and so the insert id is 'hidden' in another row of the resource.

This will give you what you want! This will work similarly with something like "INSERT INTO test (col1, col2) VALUES (?,?); SELECT * from test WHERE ID = SCOPE_IDENTITY()" and again you have to move through the resource to get at the data you want.

I hope this helps someone, since it's just wasted a good two hours of my time! Also, sorry for any errors in the code - I'm afraid I've written it off the top of my head, but hopefully you get the idea...

In some cases when mssql_query() returns rows containing fields of type SMALLDATETIME or TIMESTAMP when the data is not NULL, PHP seems to enter some kind of error state where PHP no longer outputs anything to the browser. Not even data echoed before the query! DATETIME fields seem to work without this problem though.

When this happens, PHP doesn't give any errors even with error_reporting(-1), and no errors appear in Apache logfiles either.

There seems to be a workaround by explicitly calling flush() at the end of the skript.

In my case the problem occurred only when using some basic comparison operators for integer or string fields in a WHERE clause (eg. "WHERE id = 1000").

Hopes this saves somebody the hassle I had to go through...Was struggling with an M$sql database which was poorly designed (no Identity-colums), so I had to find a way to get the last id inserted...Also struggled with the chars a while ;-)

I was tripped up by the fact that mssql_query() returns values for 'datetime' columns in an unusual format. In order to get your values returned in the usual 'YYYY-MM-DD HH:MM:SS' format, you can use the CONVERT function in your query like so:

SELECT CONVERT(varchar, INVOICE_DATE, 121) AS INVOICE_DATE ...

where 'INVOICE_DATE' is the name of the 'datetime' column. The available datetime conversion formats are listed here:

You need to escape ' with '' in mssql, however while doing a large dataset migration I ran into an issue with \0 (NULL) in the strings breaking the query. I ended up writting the below small little function, I'm sure it could be done faster/better but it has served me well.

This's note about mssql and truncating binary output from database (mostly image ...), i spent about 2 days tuning this stuff and fortunately i made the hit ... so if you're experiencing truncates of your binary data read from mssql database (it looks like incomplete, broken or even no images) check mssql section of your php.ini file and set values of mssql.textlimit and mssql.textsize variables to their maximum (2147483647) or at least bigger size than the default is ... so i hope it helps a bit, have a good time

If you'd like to store binary data, such as an image, in MSSQL, it's common to have problems with addslashes and co.

This is because the MSSQL parser makes a clear distinction between binary an character constants. You can therefore not easilly insert binary data with "column = '$data'" syntax like in MySQL and others.

The MSSQL documentation states that binary constants should be represented by their unquoted hexadecimal byte-string. That is.. to set the binary column "col" to contain the bytes 0x12, 0x65 and 0x35 you shold do "col = 0x126535" in you query.

I've successfully stored and retrieved jpeg images in a column with the "image" datatype. Here's how:

I suppose this is because I have several triggers that makes also insert after main insert call and sql server returns number of affected rows in Sql Management Studio). In php it returns only false when fetch called. So I must jump over all this 'false' rows.

'HY000' does not help me at all and same thing is returned for other errors as well. (I am not sure, but if 10007 is the number I am looking for, I do NOT want to parse the error messages. Then why do we have the notion of "err_code and err_message"?)

I think, running the following just after the 'failed' query may help:

When using this function on Linux with the FreeTDS dblib driver, some system stored procedures can return NULL values. This is because Microsoft SQL Server also uses a Windows-specific variant type in addition to the standard SQL types... like VB & OLE variants. For example:

This one took me several days to figure out so I thought I'd post the solution to save others the hassle.

When using mssql_query with freetds inside a php class, you *MUST* include the "link_identifier" in the mssql_query() call otherwise all your queries will fail. This differs from MySQL where omitting the link identifier works without problem.

watch out for mssql.timeout configuration value - if you dealing with scripts that take long time to run (backup managment, dts jobs), it might just stop running query in the middle without giving any php or sql error.

If for some reason you aren't on a windows platform (using FreeTDS etc), or on a older windows platform and are having a hard time with unicode errors with ntext and images there are two things to do:

1) make sure you odbc drivers are up to date :: or ::2) make sure to convert any ntext or image fields in your select. If you need an image from a select then you are stuck with upgrading your odbc drivers if you are getting unicode errors.

MSSQL will not let you use TEXT data in the where clause, TEXT data is BLOG data, its max size is 2,147,483,647 bytes (each character occupies one byte).The varchar and char can have max of 8000 characters, so you can use text data in a where clause if you convert as follows convert(varchar(8000),SOMETEXTDATA)

select * from tHistory where myNotes=convert(varchar(8000),SOMETEXTDATA)

Just explaining how to get date in YYYY-MM-DD format much easily, when you use convert function in SQL you usually give the format as one of the arguments. for example <br>select convert(varchar(20),getdate(),20)<br>select convert(varchar(20),getdate(),120)<br>will both return dates in yyyy-mm-dd hh:mi:ss(24h) format. you can also use <br>select convert(varchar(20),getdate(),21)<br>select convert(varchar(20),getdate(),121)<br>in yyyy-mm-dd hh:mi:ss.mmm(24h) formats.<br>So now when you have the date as string from either of the four convert functions you can either take the left part of the string or use a substring function to get the date in YYYY-MM-DD format.<br>following are few examples.<br>select left(convert(varchar(20),getdate(),20),10)<br>select left(convert(varchar(20),getdate(),120),10)<br>select left(convert(varchar(20),getdate(),21),10)<br>select left(convert(varchar(20),getdate(),121),10)<br>select substring(convert(varchar(20),getdate(),20),1,10)<br>select substring(convert(varchar(20),getdate(),20),1,10)<br>select substring(convert(varchar(20),getdate(),120),1,10)<br>select substring(convert(varchar(20),getdate(),21),1,10)<br>select substring(convert(varchar(20),getdate(),121),1,10)<br>

It would appear that MSSQL will not let you use fields of the TEXT data type in WHERE clauses.

I tried running a simple query to get account data for a particular user based on email address, but the command was not returning any data. I finally realized that this was because the emailaddress column was of the data type TEXT. When I changed the WHERE clause in the query to test against a name, which was of type VARCHAR, the query worked perfectly.

I overcame this problem by converting the TEXT field to VARCHAR in the WHERE clause, as noted below:

<?php### Field 'emailaddress' is of data type TEXT in the SQL database

# This would not work!$sql = "SELECT * FROM accounts WHERE emailaddress = 'test@test.com'";

Aplication Role is a Microsoft SQL Server 2000 feature that allow to make control what "source" use your data. It means that you can allow select, inset or update operation from your PHP code and deny it from and ODBC source, Microsoft Access or any kind of application that want to use your data.

Scenario:

Imagina you have a DAtabase named MYDB. This DB has three table. TABLEA, TABLEB and TABLEC. Imagine that your user named 'nemesis' can access to TABLEA from anywhere but you want that from table B and C access from your PHP code.

Follow this steps

[From your MSSQL Administrator]

1 -. From your Database MYDB create a new role (Standard Role). Insert this user inside this role.2 -. Edit permisions and deny any operation at TABLEB and TABLEC.3 -. Create a new Role (Aplication Role). For intance it named 'myaccess' with a password 'anypassword'.4 -. Edit permisions and allow any operation you wish at TABLEB and TABLEC

[From your source] (I don't include any control errors to simplify source)

Note: If you kill "$query = ..." you will find out that SELECT fails. If you insert that line $quey will be succeed. Now, nemesis only can take data from TABLEB and TABLEC through your PHP code. If he/She try to use that data through ODBC driver then he can not do it.

You can run a stored proceedure AND get back a result set from mssql_query(). I figured this little trick out when I realized I couldn't use the mssql_init() function group for my stored procedure stuff as I needed datetime variables to be passed, and they are not supported. However, you can "encapsulate" a snippet of stored procedure within a normal query that can be executed via mssql_query() and have a result value returned. For example, here's a query which passes a store's local date and time to a stored procedure that converts it to the GMT values that is used internally by the rest of the database structure:$temptime=time();$storeid = 68;$deptid = 70;$StartDate = strftime("%b %d %Y %H:%M:%S",$temptime);$spquery="BEGINDECLARE @date datetime, @GMreturn datetimeSELECT @date='$StartDate'execute TZ_toGMT '$storeid','$deptid',@date,@GMreturn OUTPUTSELECT @GMreturnEND";

Now, when $spquery is passed to mssql_query(), it will return with a value for @GMreturn, which can be parsed out with mssql_fetch_array() as with any other query.

Kelsey made a note that the only character that MSSQL needs "escaping" is the single quote ', and it done by using two single quotes ''. You will want to make sure that, when using strings, you contain the strings in single quotes, since you can't escape double quotes.

In addition, you won't find a mssql_escape_string() function (though there are for other DB's, i.e. mysql_escape_string()), but using:

What I experienced with Microsoft SQLserver 2000 and PHP 4.1.2 was that if you execute a query consisting of multiple queries separated by a semicolon with mssql_query is that the queries themselves are executed but the connection is dropped immediately after that. It seems that the phpdriver doesn't count on this.The EXEC solution (or maybe sp_executesql) works fine in these cases because to the db-library it is one statement.

This returned the appropriate @@IDENTITY in a valid result set. Not sure if mssql supports multiple inline commands or not. But that assumption would back the useage of the EXEC command in order to execute these properly.

The mssql_execute etc. commands for stored procs do not seem to support a DATETIME type.This means using mssql_query.Now problems occur when you want to use parameters that have Input values and Output values. SQL Server refuses to acknowledge the following...

We had a problem at first getting mssql results w/ a text field to return anything more than 4096 bytes.
The mssql.textlimit and mssql.textsize parameters in php.ini had no effect on this.
Turns out you can control this from the mssql end w/ one simple query
mssql_query("set textsize 65536");

Of course, 65536 is just an example, use whatever value you need to get back as a max.

We tested it and the setting stayed through the whole connection, no need to run that query before EVERY one of your real queries. However, it didn't seem to retain across sessions.. (sorry, can't simply run the query once and forget about it)

Hope this helps others who are banging their head on a wall like we were.

Hi All,
I was trying to insert PDF in MSSQL image datatype and had a worst time figuring out how to add PDF without encoding it with base64_encode. Encoding/decoding works best but it was conflicting with other existing PDFs in database as they weren't encoded.
The solution is to create hex string and the Trick is *NOT* to use quotes in query.

I have a mssql database with an ntext data type and was having problems as the cast solution data was still being truncated by php, i combined a couple of methods from here and elsewhere on the internet.

If you have are retrieving vast amounts of text from a SQL Server database into your website.

use SQl statements using cast e.g.SELECT CAST(details as TEXT) from table

and in the php.ini file change these values in the [mssql] section, from 4096 to whatever size and limit, remember to remove the ; from the front of the ammended line

Just in case anyone is having problems with mssql_query calling a procedure, where the procedure has multiple SELECTs, INSERTs and/or UPDATEs and some do not return any kind of a result, but some do.When trying to run mssql_query in that case an error: "Warning: mssql_fetch_array(): 1 is not a Sybase result index in ..." would result, or if one uses something like "SELECT @@IDENTITY" to return something for those statements an error: "Expected dbnextrow() to return NO_MORE_ROWS." would result.A simple fix for the error(s) is to use "SET NOCOUNT ON" statement before any statements that do not return anything and then "SET NOCOUNT OFF" before any statements that do.

this will create 2 loops:
1 - which loops through all returned recordsets. mssql_next_result will step through each recordsets
2 - this inner-loop will return all rows, as objects, from current recordset and add each object to the $result array.