I'm hoping this is an easy question.
If I run an ODBC connection via Excel I get exactly what I would expect to see from the database. When I port the query over to Xampp for testing I can not get the query to display the 4th decimal place in the results.
Here is my SQL query defined in Excel:
SELECT MC_BOM_DETAIL.finished_item, MC_BOM_DETAIL.item_num, MC_BOM_DETAIL.quantity, MC_BOM_DETAIL.line_num, IC_INVENTRY_MAST.um_stocking
FROM IC_INVENTRY_MAST IC_INVENTRY_MAST, MC_BOM_DETAIL MC_BOM_DETAIL
WHERE IC_INVENTRY_MAST.company = MC_BOM_DETAIL.company AND IC_INVENTRY_MAST.item_num = MC_BOM_DETAIL.item_num
ORDER BY MC_BOM_DETAIL.finished_item, MC_BOM_DETAIL.line_num
The php page executing the query is as follows
//Define ODBC Connection
$mas_conn = odbc_connect("odbc_connection", "user_name", "password");
//Define Query
$query = "SELECT mbd.finished_item, mbd.item_num, mbd.line_num, mbd.quantity, icm.um_stocking
FROM IC_INVENTRY_MAST icm, MC_BOM_DETAIL mbd
WHERE icm.company = mbd.company AND icm.item_num = mbd.item_num
ORDER BY mbd.finished_item, mbd.line_num";
if($result=odbc_exec($mas_conn, $query)) {
while(odbc_fetch_row($result)){
echo odbc_result($result,'quantity') .'<br>';
}
}
odbc_free_result($result);
odbc_close($mas_conn);
The results are always truncated (not rounded) to the 3rd decimal place, however I need precision to the 4th.
I looked through the php.ini file to see if that maybe the cause but came up short.
Does anybody have an suggestions?
Thank you for your time.
Solution:
The issue in my case was with the Data Definitions inside the source data. This is a bit tricky as the database is read only, and the ODBC driver is provided by 3rd party (ProvideX). After speaking with a tech at the software manufacture, I was able to change the data definitions which was set to decimal(8,3). Why Excel could read the 4th decimal and the php odbc connection could not is still unanswered. My only thought would be since Excel is running locally.
Check You Windows Localization Settings:
Panel Control->Region and Language -> Formats -> Additional Settings -> No of digits after decimal...
Related
I have an app that fetches a VARBINARY(max) data from SQL Server database. On my local environment the app connects via SQL Driver. Connection string of odbc_connect contains:
DRIVER={SQL Server}
I am fetching the VARBINARY data like this:
// Hexadecimal data of attachment
$query = 'SELECT * FROM attachments WHERE LOC_BLOB_ID = ' . $blob_id;
$attach_result = odbc_exec($connection, $query);
odbc_binmode($attach_result, ODBC_BINMODE_CONVERT);
odbc_longreadlen ($attach_result, 262144);
$attach_row = odbc_fetch_array($attach_result);
$hex_data = $attach_row['attachment_value'];
$binary = hex2bin($hex_data);
It works well. Now I need to run this app on a server where my only option is to use the ODBC driver 17 for SQL Server. Connection string contains:
DRIVER={ODBC Driver 17 for SQL Server}
And it doesn't work. It fails on line number 6 of the preview above (on odbc_fetch_array). I've tried commenting out the odbc_binmode and odbc_longreadlen lines (I assumed this driver might handle those data natively), but no luck, same result: Service unavailable timeout error.
Is there a different approach to this width ODBC Driver 17?
Edit: I found out it hangs on ODBC_BINMODE_CONVERT. If I change it to ODBC_BINMODE_RETURN, it runs within few seconds - however the output is wrong. The ODBC_BINMODE_CONVERT is indeed what I need, but it doesn't process the entire data in time (the timeout is 30 seconds), which is strange, because the VARBINARY field in the database is only 65K characters long, and it runs extremely fast on my local environment.
*Edit2: I've tried to convert the incomplete binary data fetched from the database to hexadecimal and then to PNG and it displays half of the image. So I am positive it is fetching the correct data, it just takes incredibly long to fetch that column, resulting in timeouts in almost every case.
OK. Finaly figured it out. What ended up working for me was using ODBC_BINMODE_RETURN flag instead of ODBC_BINMODE_CONVERT, and NOT using hex2bin() conversion at the end.
The code in my original question worked fine with {SQL Server}, and the following code works with {ODBC Driver 17 for SQL Server}:
$query = 'SELECT * FROM attachments WHERE LOC_BLOB_ID = ' . $blob_id;
$attach_result = odbc_exec($connection, $query);
odbc_binmode($attach_result, ODBC_BINMODE_RETURN);
odbc_longreadlen ($attach_result, 262144);
$attach_row = odbc_fetch_array($attach_result);
$binary = $attach_row['attachment_value'];
I am trying to display the contents of a field in a MS SQL database, the data type of which is 'text'. When I connect to the database with MS Excel on a PC the value looks something like:
Shipped on the: 18/10/12 Toll IPEC Connote Number: XXX XXX XXXX
When I connect to the database with PHP using the Microsoft ODBC driver for Linux, the output of the text field will display random characters, which are slightly different each time I run the exact same script. Here is what it output the last four times:
Xisep)!ØwXment.class.php))
5isep)!ment.class.php))
µ}isep)!Ø}ment.class.php))
t)!!Owner_IDt)Ø©Ø8
Not sure where it's getting the 'ment.class.php' bit from. That looks like the end of the name of one of my classes, but not one that is included in this particular script. Is the driver broken or what? All other data types (int, varchar, datetime etc) seem to display correctly, the problem only seems to happen with this one text field.
Here is the code:
<?php
require('ConnectWise.inc.php');
$config = new CW_Config;
// Connect to database
$dbcnx = odbc_connect("ConnectWise", $config->db_username, $config->db_password);
// Query database
$query = "select * from Billing_Log where Invoice_Number = '24011'";
$result = odbc_exec($dbcnx, $query);
while ($row = odbc_fetch_array($result)) {
echo $row['Top_Comment'] . "\n";
}
odbc_close($dbcnx);
Here is the output of my last few attempts:
\3ȶä!!¶äY!
öÈö§!!ö§Y!
&Èö×!!ö×Y!
Looks like you're getting an overflow. For some reason SQL is passing the length of your text field as 0, which to SQL means "long" but to PHP means "I dont know" and so PHP is showing whatever is in its memory at the location its expecting data (or something like that - any PHP experts care to explain?).
I've seen this with varchar(max) before but not text. (Converting to) Text is normally the way to fix it. So maybe I'm wrong.
Hope this is of some help. Im not a PHP developer, I just have to use it occasionally, and this sounds much like a painful experience I've gone through before :)
I'm storing a long text with mssql_query();
And Using the field with datatype called 'text'.
I tried with different long strings by using str_repeat(), the page takes long time, but in the end submits the result.
When I retrieve the result however, I get only 4096 bytes nomatterwhat.
I tried to retrieve the value with management studio too, and it gets the same outcome.
It looks to me like a storing problem to me. Please advice something... I'm confused.
EDIT for these who asked, this is what I'm using:
function sql_escape($sql) {
/* De MagicQuotes */
$fix_str = stripslashes($sql);
$fix_str = str_replace("'","''",$sql);
$fix_str = str_replace("\0","[NULL]",$fix_str);
return "'".$fix_str."'";
}
$query=mssql_query('update prod_cat set htmlbottom='.sql_escape(str_repeat('\'choose_cat ', 122000)).
' where ID=1' );
$query=mssql_query('select htmlbottom from prod_cat where ID=1');
$a=mssql_fetch_assoc($query);
echo strlen($a['htmlbottom']);
Microsoft's PHP driver (for reference): http://www.microsoft.com/en-us/download/details.aspx?id=20098
But if you don't want to (or can't) change drivers, from this site:
You need to increase the maximum size of a text column to be returned from
SQL Server by PHP. You can do this with a simple SQL query:
SET TEXTSIZE 2147483647
Which you can run with the following PHP (best run just after you make a
connection).
mssql_query("SET TEXTSIZE 2147483647");
A better way to work around the issue is to change the "textlimit" and
"textsize" settings within php.ini, like so:
mssql.textlimit = 2147483647
mssql.textsize = 2147483647
Your MSSQL driver is truncating the text. If you can't change datatypes, drivers, etc., this should fix the issue for you.
I'm working on a web app that is using PHP and MSSQL. One of my requirements is to use the field descriptions in MSSQL in part of the web app.
I know the Stored Proc. for adding descriptions in MSSQL is:
EXEC sp_addextendedproperty
#name = N'Description', #value = 'Description goes here',
#level0type = N'Schema', #level0name = 'schemaname',
#level1type = N'Table', #level1name = 'tablename',
#level2type = N'Column', #level2name = 'columname'
GO
I am having problems converting this into php, however.
I'm trying to use the mssql_init/bind/execute commands, but I keep getting an error that I am not sure how to troubleshoot.
PHP Code:
$query = mssql_init("sp_addextendedproperty",$dblink);
mssql_bind($query,"#name","N'Description'",SQLVARCHAR);
mssql_bind($query,"#value",$_POST['description'],SQLVARCHAR);
mssql_bind($query,"#level0type","N'Schema'",SQLVARCHAR);
mssql_bind($query,"#level0name","dbo",SQLVARCHAR);
mssql_bind($query,"#level1type","N'Table'",SQLVARCHAR);
mssql_bind($query,"#level1name",$_POST['tableselect'],SQLVARCHAR);
mssql_bind($query,"#level2type","N'Column'",SQLVARCHAR);
mssql_bind($query,"#level1name",$_POST['column_name'],SQLVARCHAR);
mssql_execute($query)
My error is:
An invalid parameter or option was specified for procedure 'sp_addextendedproperty'. (severity 16)
I don't know enough about stored procedures to fully troubleshoot this. Can somebody help me out?
Unless you've simply made a typo posting your sample code, you're using #level1name twice. The second occurrence should be #level2name instead.
Ok so I got this piece of vendor software that they said should be run on an apache php server and MySql database.
I didn't have either of those so I put it on a PHP IIS server and I converted the code to work on SQL server.
ex.
mysql_select_db -> mssql_select_db
(among other things)
So I have the following code in a php file
$query = "SELECT * FROM TableName WHERE KEY_FIELD = '".$keyField."';";
$result = mssql_query($query);
$arr = array();
while ( $obj = mssql_fetch_object($result) )
{
$arr[] = $obj;
}
echo '{"results":'.json_encode($arr).'}';
and my results look something like this (captured with fiddler 2)
{"results":[{"KEY_FIELD":"57", "My30characterlongfieldthatiscu":"GoodValue"}]}
"My30characterlongfieldthatiscu" should be "My30characterlongfieldthatiscutoff"
Kinda weird, no?
The vendor claims that the app works perfectly on their end.
I'm thinking this is some sort of IIS PHP limit, is there a way around it or can I expand it?
I found this solution
http://www.php.net/manual/en/ref.mssql.php#74834
but I don't understand it.
Thanks!
See http://bugs.php.net/bug.php?id=33060 - this is what's causing your issue.
You might also want to consider changing the column names - more than 30 characters sounds excessively long.
http://docs.php.net/manual/en/mssql.requirements says:
Note: On Windows, the DBLIB from Microsoft is used. Functions that return a column name are based on the dbcolname() function in DBLIB. DBLIB was developed for SQL Server 6.x where the max identifier length is 30. For this reason, the maximum column length is 30 characters. On platforms where FreeTDS is used (Linux), this is not a problem.
Is using the sqlsrv extension instead of mssql an option?