-
Notifications
You must be signed in to change notification settings - Fork 373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Money, Decimal datatypes #415
Comments
@genyslt , The answer to both questions is that PHP does not support decimal type. All numbers that are not integers are represented as float in PHP. To preserve the precision of the decimal or money types, the values our driver return is a stringified number of exact precision that is specified when you create your table (money has a scale of 4, and your decimal type has a scale of 2). |
It's not normal way to get ".00" number. The prices on the market also going scale of 2. On http://php.net/manual/en/book.mssql.php driver - every works fine. I trying to migrate from php 5.6 and mssql driver to php 7.1.5 and sqlsrv driver - and get some missunderstandings. Can it be a configuration setting? Full internet writing about this problem, every programmer repairs results to show to the user , so i think this is very actual problem and driver must solve this problem. P.S. I see SQLSRV_ATTR_FETCHES_NUMERIC_TYPE configuration on PDO::SQLSRV, on SQLSRV this configuration option didn't work. |
From here you can see that the money data type in MS SQL Server has a scale of 4. I understanding a lot of people have problem with numbers being stored as strings in PHP, but since PHP does not support decimal type, our best approach to preserve the precision of a decimal number is by returning them as strings of exact precisions. If we truncate it to two decimal places to make it look "nice", then the actual precision of money would be gone. As for SQLSRV_ATTR_FETCHES_NUMERIC_TYPE in the PDO_SQLSRV driver, it only works for integer types (i.e., whole number) and float types (inexact numbers), but it doesn't work for decimal types. This is again due to the need of preserving the precision of decimal numbers. If you really wish to make your number look as your desire, you can try to use the PHP function floatval(). But be careful if you do a lot of arithmetic operations on inexact numbers (especially when working with money), it could lead to a loss in precision. Thanks. |
It's developer problems since PHP does not support decimal type? I think you are driver developer, and you must solve problems to WW (World wide) developers, that developers would be easier and easier to deal with such situations. You "understanding a lot of people have problem with numbers being stored as strings in PHP" but not doing anything to help peoples save time.. Let's count: 1000 peoples use your driver. How you think time you waste of these peoples? My dirty solution to workaround this by every query, each row (EVERY QUERY!!! EACH ROW!!!):
P.S. When i say You i mean Microsoft - nothink personally to You. |
It is our design decision preserve the four decimal places in money types, since again SQL Serve money types has a scale of 4. Although some users may wish to represent money as float or as a two decimal places stringified number, more users would rather preserve the precision of money type. I've explained the risk of not preserving the precision of decimal types here. As for the leading 0 being dropped from '0.00' issue, this is the numeric literal syntax designed by the Microsoft ODBC driver (see here). If you want to format your numbers as you want, your SQL command is wrong. You should format the result from SQL Server like this: See here for more information on number formatting. |
Can you add configurable connection param on this? |
Hello @genyslt |
Same problem here, very annoying, need to use number_format() on each row containing ".00" results... @yitam And what's about people don't have any control of the database ? i can't use |
@alexandre-tobia please clarify what you mean by having no control of the database or elaborate why you can't use FORMAT easily. |
An obvious scenario in defense of @alexandre-tobia: Dropping the leading 0 is an unfortunate breaking decision by the unixodbc driver development team. Anyone coming from I know it's not this extension's issue specifically, but the driver upon which it's dependent causes a breaking change and forces developers to go through thousands of files and millions of lines of code built up over the years to add workarounds like |
@yitam I'm external developper working for a big company. I essentialy use stored procedures for getting datas from their databases. I can't modifiy the stored procedure's queries, so use i agree with @lifzgreat, need to use "number_format" in many places... |
Hi @alexandre-tobia, please understand that not all users have the same preferences. While someone might want high accuracy with money data, others might prefer only two decimal places or even with the returned values rounded up/down. For example, the user in #291 wanted decimals returned as numeric values instead of strings. We have valid reasons to preserve the precision / scale as mentioned by @v-kaywon earlier, and there exist methods like In your case, you might want to define some helper method(s) to take care of your formatting issues. Alternatively, you might want to follow the example in #291 to modify the drivers to suit your needs. |
Please understand that preferences aren't the point. The point is developers are now seeing a changed default output after years of built up code. I think it all comes back to the unixodbc driver that the Even worse, the unixodbc driver drops the leading 0 when a number is less than 1 and greater than 0. That's just a terrible breaking decision. Imagine if PHP said devs can no longer use |
Hi @lifzgreat , @alexandre-tobia , We get it. There is a large PHP code base written against the default behavior of the old mssql PHP driver. Moving to this driver becomes a lot more difficult when its default behavior is slightly different and affects the way data is presented to the application. Ideally, we would like to be able to provide a path that does not require such a high effort in migrating from the old driver. I think the idea of PHP driver configuration options to modify the default behavior in these scenarios is worth considering. I'm going to tag this issue as a feature request for consideration in a future release. Regards, |
Hi @lifzgreat , @alexandre-tobia , @genyslt, Just want to make sure I understand what you want to be configurable. To retain the zero to the left of the decimal dot and/or the number of decimals? Or do you want something similar to the built-in PHP function |
Hi @yitam I had to read over this as it was from 6 months ago but retaining the leading 0 and having money display the standard 2 decimals is what we had expected at that time. Since then, we had to go through and rework existing code that dealt with those things. It seems to me most people would expect to see a leading 0 and 2 decimals for money, so it seems that'd be best as the default output. That said, if you provide the ability to configure default output, I think that's a step in the right direction. |
Thanks for the reply @lifzgreat. Yes we are looking into providing a configurable option (the default remains the same, however). In any case, the money / decimal output is still a string to keep precision / accuracy, with some rounding if necessary. So leading zero and number of decimals are the desired options. |
Sounds great, thanks @yitam. |
It's absolutely correct to return Currency etc. as strings. Tip for PHP-Developers: If you need to operate on such values, you should use libraries that provide abstraction on top of e.g. bcmath. See https://packagist.org/packages/litipk/php-bignumbers or https://packagist.org/?query=decimal Side fact (please correct me, if I'm wrong): I'm building a json api. Json floats are unprecise, too. Additionally you don't know which language parses the json. JS and PHP would loose the precision even if JSON could handle it. So you should transfer Currency fields as strings in JSON, too. |
Indeed, @mschop, so thank you. We are considering this feature request, and most likely we would only provide a configuration option to format the number of decimal digits (with leading zeroes if necessary) for decimals / numeric data types during fetching, and rounding is sometimes inevitable. The data itself will not be altered however. |
Can you elaborate a little bit more? I did not understand the question. |
Hello @Jeeppler , the original problem in this issue is about money and decimal / numeric types because they are always returned as strings. However, for other numeric types like floats or real, they can be returned as numbers, not strings. My question for you is whether you want leading zeros applied to all number strings, whether they are of float types or decimal types. I hope I have made myself clear. |
@yitam sorry for the confusion, I have this problem:
Float/double types are handled well by both PHP and JavaScript as well as PHP's Here is an example:
Here is a JavaScript example:
|
Yes, it's a design decision to return money, decimal or numeric types as strings to preserve accuracy. See the discussions above, for your interest. In this case, @Jeeppler , you're also mainly concerned with leading zeros with money, decimal or numeric types, just like the others in this issue. Please correct me if I have misunderstood you. |
@yitam yes, exactly. I am concerned with the leading zeros with money, decimal or numeric types. |
Yes @Jeeppler we plan to incorporate the pull request in the next preview. I'm also writing instructions on how to use the new configurable options. Please note that we have recently decided to limit configuring number of decimal places to only money / smallmoney fields. |
I'm not sure I understand your question, @Jeeppler. But once this pull request is merged, if the decimal data is shown as |
@yitam yes, that answers my question. Do you have a release date for driver version 5.4? |
@yitam thanks for the link. Please let me know, by adding to this issue, the moment you have the documentation for the configuration settings available. Or is there a way for me to try out the changes before the official release? |
@Jeeppler you can try building our drivers from the current dev branch. In the meantime, you can also browse the documentation that is recently updated. Just so you know, we will not make last minute changes at this point, but we welcome feedback because this is a preview release. |
@yitam thanks, I really appreciate the link to the updated documentation. However, I saw starting with: |
@Jeeppler no 5.4.0 was already out awhile ago, and this upcoming preview is 5.5.0 |
@yitam perfect. When will 5.5.0 preview or 5.5.0 be available? When will 5.5.0 be released? Will it be released in 2018 or do we have to wait until somewhere in 2019? And if it is 2019, what will be the approx. release date? |
We can't give you an exact date @Jeeppler but it will be 2019. We are planning to add yet another feature before we can release. Please subscribe to the blog if you like. |
@Jeeppler fyi, 5.5.0-preview is published, and we welcome feedback. I'm going to close your related issue. |
Thanks. Installing 5.5.0-preview was easy. However, I do not know how to configure Docrine ORM to set the new
and
the connections work, but the decimal issues still persist. I do not know if I set the |
hi @Jeeppler They may not support a preview release. To prove that the new feature works, please run a quick test by using a simple php script below:
The output should be
|
@yitam thanks for the code snippet. I can confirm that it works. I got the same result as you. One issue I had with your code is the naming of variables. I was not 100% what I modified your code snippet to illustrate my point:
The other parameters which is not explained is the how to set a different port. Good documentation is always appreciated. |
I do not know if Doctrine supports preview driver. However, at some point in time they will likely add the configuration to some of the next releases. However, to be able to do the code changes the preview driver are beneficial and they have to be aware of the changes. I went ahead and created an issue in the DoctrineBundle: https://github.com/doctrine/DoctrineBundle/issues/893 |
Yes, I agree. Thanks for the feedback and the documentation already modified, @Jeeppler |
Driver version 5.6 is released officially: Production Release for the PHP drivers Version 5.6.0 for SQL Server. This release implements the decimal feature discussed here. |
Thanks @Jeeppler |
Hello,
Issue
I have several fields on sql table:
PHP Code:
The result on $res_array have some issue:
100.0000
.00
Question
Try it select on sql server management studio:
At the management studio the result is good.
The result i see on the manager and on $res_array must be same.
System info
PHP version: 7.1.5
Linux version: Ubuntu 16.04.2 LTS
sqlsrv_client_info:
[DriverName] => libmsodbcsql-13.1.so.8.0
[DriverODBCVer] => 03.52
[DriverVer] => 13.01.0008
[ExtensionVer] => 4.0.8.0
sqlsrv_server_info:
[SQLServerVersion] => 12.00.2000
The text was updated successfully, but these errors were encountered: