I need your help please.
We have a PHP application running on MySQL, and we need to use PostgreSQL for a new customer.
the problem is that when we insert empty strings in a field of type numeric, we get an error.
I think we should actually use NULL instead of empty string.
However we would like to avoid having to recode all the SQL code of our application, my question is whether it is possible in the structure of a table (or elsewhere) to ensure that our numeric column accepts empty values? or convert them to NULL?
In the documentation I have seen that it is possible to define your own types, it is possible for example to create a type based on numeric and ensure that it accepts empty values?
If yes how? I found no solution
Thank you
the problem is that when we insert
empty strings in a field of type
numeric, we get an error.
That's correct, a string isn't a number. Not even an empty string.
I think we should actually use NULL
instead of empty string.
That's correct, your current SQL is wrong. If your MySQL-configuration would use a better SQL_MODE, your queries will also fail on MySQL. Fix your code, it's by far the best option you have.
Hacking around by creating dummy datatypes is just a hack, it's not a solution for bad SQL. The problem is your SQL, not your database.
Related
Is there any case for using an empty string instead of null? I'm looking for any domain or business context where you would want to use the empty string instead of using null
I'm pondering this in terms of the HTTP stack, for example in php a request with a query string that looks like https://example.com/something?key= would be interpreted as an empty string.
var_dump($_GET['key']);
string(0) ""
And for every use case my limited imagination can conceive, this should always be converted to null so why would anyone have a need to store "" in a database field or something like that?
The concept of NULL is used to represent a value that is not known. This is easier to grasp in the database context, where an entire row is inserted in the database at a time. The fields whose values are not known are initialized with NULL.
The programming languages that support the concept usually use NULL as the value of the uninitialized variables. This usage shifts the general perception of NULL towards the idea of "not set". In fact, the semantics of NULL in this context is also "unknown".
An empty string ('') is a different thing. It represents the absence of any character in a string. It doesn't mean the value (of type string) is not known; it is known: it is empty. Using it instead of NULL is a logic error.
In the context of the HTTP GET request whose URL is https://example.com/something?key=, processed by a PHP script, $_GET['key'] is '' (the empty string). The value is known, the key variable is present in the URL and its value is the empty string. But $_GET['foo'] is correctly evaluated by PHP as NULL. The value is simply not known. It is not the empty string; it can be any value but since it was not sent in the URL we cannot know it.
As the database is concerned, an empty string and a NULL values are two different things. You can tell them apart and query each other specifically. As a weakly typed language, PHP tends to blur the line, but that doesn't mean it is the case everywhere in the software ecosystem.
On the other hand, one of the primary uses of php is to handle http form values, which are all of type string by nature. Maybe that doesn't help either.
PHP has auto type conversion function, but when do we ever need to use settype()?
The only example I have tried that needs settype() is when I need to put data from users to the database using PDO, where attributes are defined as int, decimal, or etc. I need to first convert the type (from string to int for example and when I do not use settype(), it seems to have error coming out.) BUT are there any other reasons why people gonna use settype()? Correct me if I am wrong. Thanks.
Maybe many just misunderstand my question. Let me re-phase it.
When do I ever need to use settype() since PHP auto converse type when it is needed? For example, PHP will not convert data type when inserting data into database. Therefore we should use a settype() to convert data to the specified type. If not, error will be raised.
Can anyone give me more example other than connecting to the database where settype() is needed? Thanks.
I am using PHP's PDO to query a MySQL database. It returns numbers and integers as strings, and is messing with my JSON.
Is there a better way of fixing it other than type casting the values row by row?
array(2) {
["name"]=> string(11) "Preliminary"
["sell_price"]=> string(6) "864.00"
}
If you are using php 5.3.3 or higher you can use JSON_NUMERIC_CHECK as the second argument to json_encode to do this.
See: http://us3.php.net/manual/en/function.json-encode.php
Although #Explosion Pills works in this case for #user1032531's needs, it's not addressing the 1st source of the problem.
As you can see in the original question, on the PHP side the value from sell_price is already a string, although, as the user said, in the database it's stored as a "number" (we don't know if it's a DECIMAL or a FLOAT).
Well, when using PDO with MySQL a proper config may be required in order to get "numbers" as "numbers", as user #jameshfisher pointed out in his comment. You can follow his link in order to get almost everything you need to get it working.
Appart from that, the accepted answer is working because without the use of the JSON_NUMERIC_CHECK json_encode will send everything as text no matter the type of the variable, and when using it it will convert the value to a type based on guesses rather than the type of the original var.
Just wondering, if is there any class, function or ideia on how to validate a specific value/variable against a mysql data type.
We've got in PHP the is_int() is_string() is_float() etc etc... But we do not have them all. Or do we? Any Cheat sheet? Any thoughts?
EDIT:
The point basically is:
Go trought a array of values (comming from a CSV for instance).
I know what table, and have all the column information (data type s well) (with adodb).
Just check if each value fits in a specific column...
If the data is coming from a CSV file, you have to remember that all the values are going to be strings (even numeric strings still have a string type).
So you can't use is_int()/is_float()/etc., because that only tells you about the type or the variable. You could use is_numeric() to check the value, but this will allow for things like exponential notation like "+0123.45e6". Sometimes ctype_digit() can be useful for testing integers for this reason, since it will only allow the numbers 0-9 to be present in a string for it to return true.
Regular expressions can also be used to identify pattern-based data types, but you do have to watch for performance overhead when dealing with large data sets. It's almost always advisable from a performance perspective to use the preg_ family of functions instead of the ereg functions.
If you're validating things like ENUM or SET types, you'll probably need to make an array containing legal values (or extract these with a query) and then check the value against them with in_array().
For CHAR/VARCHAR fields, you could parse the column definition and then check whether the length of the value falls within the constraints.
If the NULL type is allowed on any of your columns, you'd also need to check against this (and probably map empty values or the string "NULL" to an actual NULL value).
If you're looking to actually escape these values properly, look into using prepared statements and the PDO (PHP Data Objects) extension. This allows MySQL to properly escape the data based on type. (You can also use prepared statements with MySQLi.)
If you're looking for specific data types and how to identify them, then you might want to edit your question to facilitate more complete answers.
Original Question
mysql-server-6.0.10
I have this problem, I'm using the COMPRESS function to update a field with a BASE64 encoded value. The "updated" base64 string is only slightly different than the value that is currently in the database but it IS different. The only part is different is the last few bytes of the string. The problem is that mysql is seeing these values as the SAME and therefore skipping the update. It returns without error letting my program thing it did what it was told but then you go back and the data is unchagned.
For example, the first one is base64 string that was previously INSERTED to the db, the second one is what I'm trying to overwrite with:
YToxOntpOjA7YToxOntzOjE1OiJ0cmFja2luZ19udW1iZXIiO2k6MjM0MjM0MjM0MzI0MDAwO319
YToxOntpOjA7YToxOntzOjE1OiJ0cmFja2luZ19udW1iZXIiO3M6MTU6IjIzNDIzNDIzNDMyNDExMSI7fX0=
I'm running this query:
UPDATE TABLE SET fieldname=COMPRESS('YToxOntpOjA7YToxOntzOjE1OiJ0cmFja2luZ19udW1iZXIiO3M6MTU6IjIzNDIzNDIzNDMyNDExMSI7fX0=') WHERE id = 'SOMEID';
Mysql comes back with 0 rows affected.
I can reproduce this in an SQL Query window via PHPMyAdmin so I know its not a problem with code.
How can I force this to just update regardless if the strings BEGIN the same way, since it obviously inst checking the entire string? Right now my workaround is to clear the present data with one query, then run another query to update against nothing. This is inefficient though and I'm not happy with it.
First question update
I actually found out this is a result of a PHP bug with JSON_NUMERIC_CHECK!
The value was getting saved in the database properly (couldnt tell because of the compression) but when my script to go back was loading the data out of the database via JSON_ENCODE the values were getting mangled by JSON_NUMERIC_CHECK.
See the bug report I filed:
https://bugs.php.net/bug.php?id=60111
Second question update and solution
So it really turns out I was way ahead of my self on this. I was using JSON_NUMERIC_CHECK incorrectly. I was using it as a blanket solution to ensure all numeric values would be, well, numeric. The flaw in this logic is that JSON_NUMERIC_CHECK's purpose in life is to attempt to convert all numeric strings to integers, in 32-bit OS environment there is a limit to how many digits an int val can be and thus using the exponential expression as it should!
It comes down to the fact that in my system, there is a possibility of a [tracking number] could actually be an extremely long string of just numbers. JSON_NUMERIC_CHECK was doing exactly what it was suppose to do by converting this to an exponentially expressed int val.
The actual fix to this was to not use JSON_NUMERIC_CHECK and to make sure that my var types were correct where I actually needed int vals before creating the object that is later passed to the front end via JSON.
Phew, a mouthfull, but i figured if anyone else runs into this problem it might be helpful. Chao!
I'm sorry guys, nevermind, the problem is that value i'm supplying is being treated as INT instead of STRING and its over the max size of an INT so its resetting to the MAX INT and therefore being the same string.
Sometimes just thinking through it enough to post a problem on here is enough to help me figure it out :)
UPDATE:
I actually found out this is a result of a PHP bug with JSON_NUMERIC_CHECK!
The value was getting saved in the database properly (couldnt tell because of the compression) but when my script to go back was loading the data out of the database via JSON_ENCODE the values were getting mangled by JSON_NUMERIC_CHECK.
UPDATE:
I'm actually just way ahead of my self. using JSON_NUMERIC_CHECK incorrectly. My bad!