Floats are not saved correctly into SQLite table using PHP - php

I'm using SQLite 3 with PHP.
The SQLite table consists of 2 INTEGER and one FLOAT column. When saving data into this table using PHP floats are not saved correctly (default value is stored instead). The two integer columns are saved. Any ideas what could be wrong? Thank you.
Simplified code that actually works correctly:
$conn = new SQLite3('dbFileName');
$conn->query("CREATE TABLE data (
id INTEGER NOT NULL DEFAULT 0 ,
ts INTEGER NOT NULL DEFAULT 0 ,
value FLOAT NOT NULL DEFAULT 0
);"
);
$conn->query("REPLACE INTO data(id,ts,value) VALUES ('1','1234567890','12.1')");
-> 1|1234567890|0

This is just a suggestion, seeing as I have never used SQLite, but are you sure the numbers should be quoted? That seems somewhat odd to me.
Try:
$conn->query("REPLACE INTO data(id,ts,value) VALUES (1, 1234567890, 12.1)");

Sqlite data types are typeless, so your queries have to work:
all the following queries works for me
REPLACE INTO data(id,ts,value) VALUES ('1','1234567890','12.1');
REPLACE INTO data(id,ts,value) VALUES ('1','1234567890','12,123')
REPLACE INTO data(id,ts,value) VALUES ('1','1234567890','abc');
Check your PHP variable, you might have a bug and you pass a null variable.

Related

Return BLOB column Which is Empty Or Not Empty as 1 or 0

I have a table with BLOB column that some row has BLOB, some empty.
1 Apple BLOB-8KiB
2 Banana
3 Pear BLOB-6KiB
4 Orange BLOB-7KiB
Is there any way I can use PHP MYSQL to get the array like this:
$fruit = array(
array("1",Apple,1),
array("2",Banana,0),
array("3",Pear,1),
array("4",Orange,1)
);
I just want to change the BLOB data with 1, Empty with 0 in my PHP array. Pls help.
Your select statement can use IF and ISNULL (note these are not widely implemented in the same format on different database backends, this is for MySQL).
So you would use:
SELECT ID, Name, IF(ISNULL(BlobField), 0, 1) FROM TableName
IF allows you to choose one of two values according to a logical operation.
ISNULL returns true or false according to whether or not the value is NULL

Value not compatible when doing merge in DB2

I'm trying to perform a merge based on a parameter from a previous select within a php script but I"m getting the error "SQL0408 - Value for column,variable, or paramter QUANTITY not compatible"
In my destination table QUANTITY is data type INTEGER
In my select query, I'm casting the value as an int (which it already is in the table, I'm just casting everything to be safe)
cast(MAX(orqtyc) as int) AS QUANTITY,
Then in my MERGE I'm casting as INT
MERGE INTO HNORMANTEST.PLACEMENTS AS P
USING(VALUES(
CAST(:QUANTITY as INT),
))
Using this param
$params = [
":QUANTITY" => $row["QUANTITY"],
];
Why would it say it's not compatible?
Did you try it by putting directly value instead of via param and see if it works or not.
Another thing you can try is remove the first casting which may not be needed. As you said QUANTITY is already a INT datatype.
Please try both the variation. If both variation givens same error then there might be some product limitation/bug.
You need to pass on the DB2 version where you have tried to look further in it.

Mysql not inserting binary data properly

I am working on data compression and for some reason i need only 8 bits.
I am converting number by decbin() and then inserting it in the mysql, the mysql column data type BIT width is 8 bit. I used mysql_query("INSERT INTO n (reading) VALUES (b'".$value."')") and tried this one toomysql_query("INSERT INTO n (reading) VALUES (".$value.")"). Before inserting the value is fine but after insertion its not the same value, it changes the value for example before insertion it echo the value 116 then I echo its binary value 1110100 and it insert the value in mysql column is 00110000.
function delta($reading){
global $flag;
$delta = $flag - $reading;
saveDelta(decbin($delta));
}
here is the other function where it saves the value
function saveDelta($dif) {
mysql_query("INSERT INTO n (reading) VALUES (".$dif.")");
}
The syntax "INSERT INTO n (reading) VALUES (b'".$value."')" should work provided that $value is properly encoded as a string of '0' and '1'.
EDIT: I noticed you didn't provide any "sequence number" while inserting your data. But, please remember that without using a proper ORDER BY clause, you cannot retrieve your bytes the order they where entered at first. Maybe you think you read "116" but MySQL return an other row from the table?
Here are some usage examples, First using the BIT type:
CREATE TABLE b (value BIT(8));
INSERT INTO b VALUES (0),(1), (255);
INSERT INTO b VALUES (b'00000000'),(b'00000001'), (b'11111111');
Please note that when retrieving BIT columns you will obtain signed result (i.e.: storing 255 will read -1).
You could retrieve your data either as signed 10-base integers or binary form (with optional padding):
SELECT value FROM b;
SELECT BIN(value) FROM b;
SELECT LPAD(BIN(value), 8, '0') FROM b;
As of myself, I would prefer the TINYINT UNSIGNED. This is an 8 bit type which support the same syntax for values (either <10-base digit> or b'xxxxxxxx') -- but will accept the UNSIGNED specifier:
CREATE TABLE t (value TINYINT UNSIGNED);
INSERT INTO t VALUES (0),(1),(255);
INSERT INTO t VALUES (b'00000000'),(b'00000001'), (b'11111111');
You could retrieve your data either as unsigned 10-base integers or binary form (with optional padding):
SELECT value FROM t;
SELECT BIN(value) FROM t;
SELECT LPAD(BIN(value), 8, '0') FROM t;
See http://sqlfiddle.com/#!2/4ff44/6 to experiment with both of them.

MD5 Hashes not matching

I am trying to match a md5 has (generated through php) to its original value in a SQLExpress database.
I am using the following function in my SQL query
master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', 'ID'), 1, 0)
Where 'ID' is the field in the database.
However they both seem to return different values for the md5 hash. I have been using '12290' as a static value to test this.
php md5() returns: 0bd81786a8ec6ae9b22cbb3cb4d88179
The following SQL Statement returns the same output:
DECLARE #password VARCHAR(255)
SET #password = master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', '12290'), 1, 0)
SELECT #password
Yet when I run the following statement from the table:
SELECT ID, master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', CONVERT(NVARCHAR(255), ID)), 1, 0) AS temp
FROM Clients
ORDER BY ID ASC
The 'temp' value matching to the 'ID' value of 12290 returns: 1867dce5f1ee1ddb46ff0ccd1fc58e03
Any help on the matter would be much appreciated!
Thanks
Python helped me to help you.
>>> from hashlib import md5
>>> md5('1\x002\x002\x009\x000\x00').digest().encode('hex')
'1867dce5f1ee1ddb46ff0ccd1fc58e03'
NVARCHAR is Unicode type and it seems from the above experiment that '12990' is stored as UTF-16LE in your database: '1\02\09\09\00\0'.
Assuming that the data encoding in the PHP is UTF-8 data and you don't want to change the existing data in the database, this is how you can fix your PHP script:
<?php
$password = '12290';
$hash = md5(mb_convert_encoding($password, 'UTF-16LE', 'UTF-8')) . "\n";
echo $hash;
?>
Output:
susam#swift:~$ php utf16le-hash.php
1867dce5f1ee1ddb46ff0ccd1fc58e03
In case the data in PHP is in some other encoding such as ASCII, ISO-8859-1, etc. you can change the third argument to mb_convert_encoding accordingly. The list of all supported encodings is available at: http://www.php.net/manual/en/mbstring.supported-encodings.php
Also, see http://www.php.net/manual/en/function.mb-convert-encoding.php
I don't have SQL server to test this on, but the CONVERT command might be creating the NVARCHAR with 240-odd trailing blanks (as you have specified NVARCHAR(255))
Try setting the NVARCHAR to the length of the ID to test:
ARE #password VARCHAR(255)
SET #password = master.sys.fn_varbintohexsubstring(0, HASHBYTES('MD5', CONVERT(NVARCHAR(5), '12290')), 1, 0)
SELECT #password
Try with different lengths in the CONVERT - is there any difference?
One of two things is most likely the problem:
Either the ID column in that row has a value not exactly equal to '12290' (e.g. extra whitespace)
Or the CONVERT function produces such a value
In any case, a standard debugging approach would be to use an SQL query to SELECT the string lengths of that ID field and the return value of CONVERT; if either is not equal to 5, you found the error.
Alternatively you can perform a dump of the table in question including data, and look at the generated INSERT statement to see what the database says the value in that column is.

Why an ENUM("0", "1") is saved as an empty string in Mysql?

I have a MYSQL table with an ENUM field named "offset" and some other columns. The field is defined as:
ENUM(0,1), can be NULL, predefined value NULL
Now I have two server. A production server and a development server and the same PHP script used to create and to update the database.
First step: the application create the record witout passing the "offset" in the CREATE query.
Second step: the application ask to the user some data (not the "offset" value), read the row inserted in step one and make an array, update some field (not the "offset" field), create a query in an automated fashion and save the row again with the updated values.
The automated query builder simple read all the field passed in an array and create the UPDATE string.
In both systems I obtain this array:
$values = array(... 'offset' => null);
and convert it in this same query passing the values in the mysql_real_escape_string:
UPDATE MyTable SET values..., `offset` = '' WHERE id = '10';
Now there is the problem. When i launch the query in the production system, the row is saved, in the development system I got an error and the db says that the offset data is wrong without saving the row.
From phpmyadmin when I create the row with the first step, it shows NULL in the offset field. After saving the field in the system which give no errors, it show me an empty string.
Both system are using MySQL 5 but the production uses 5.0.51 on Linux and development use 5.0.37 on Windows.
The questions:
Why one system give me an error an the other one save the field ? Is a configuration difference ?
Why when I save the field which is an enum "0" or "1" it saves "" and not NULL ?
Why one system give me an error an the other one save the field ? Is a configuration difference ?
Probably. See below.
Why when I save the field which is an enum "0" or "1" it saves "" and not NULL ?
According to the MySQL ENUM documentation:
The value may also be the empty string ('') or NULL under certain circumstances:
If you insert an invalid value into an ENUM (that is, a string not present in the list of permitted values), the empty string is inserted instead as a special error value. This string can be distinguished from a "normal" empty string by the fact that this string has the numeric value 0. ...
If strict SQL mode is enabled, attempts to insert invalid ENUM values result in an error.
(Emphasis added.)
strager's answer seems like a good explanation on why your code behaves differently on the 2 environments.
The problem lies elsewhere though. If you want to set a value to NULL in the query you shound use exactly NULL, but you are using mysql_real_escape_string() which result is always a string:
$ php -r 'var_dump(mysql_real_escape_string(null));'
string(0) ""
You should handle this differently. E.g:
$value = null
$escaped_value = is_null($value) ? "NULL" : mysql_real_escape_string($value);
var_dump($escaped_value);
// NULL
Some DB layers, like PDO, handle this just fine for you.
If you want it to be NULL, why don't you do this in the first place:
UPDATE MyTable SET values..., `offset` = NULL WHERE id = 10;

Categories