How can I get an update another field (whole column) the difference of time in (TIME 00:00:00) format in my MYSQL phpMyAdmin database
<?php
$con=mysqli_connect("***","****","****","******");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
mysqli_query($con,"UPDATE members SET time_on = current_time-logon_time");
?>
I keep getting 0:00:00 and no results when I do this in PHP. The other times our fine, just trying to get the difference and update all fields in the time_on column.
You should use timediff()
mysqli_query($con,"UPDATE members SET time_on = timediff(current_time,logon_time)");
You can use TIMESTAMPDIFF() to get the difference between two dates and/or datetimes.
Try this:
UPDATE members
SET time_on = TIMESTAMPDIFF(SECOND, logon_time, current_time)
This will set the difference in seconds.
Just to expand on why the other answers are right: You're doing MATH on times, which doesn't work as you expect:
mysql> create table foo (x time, y time);
Query OK, 0 rows affected (0.01 sec)
mysql> insert into foo (x, y) values ('14:15:16', '09:08:07');
Query OK, 1 row affected (0.00 sec)
mysql> select * from foo;
+----------+----------+
| x | y |
+----------+----------+
| 14:15:16 | 09:08:07 |
+----------+----------+
1 row in set (0.00 sec)
mysql> select x - y from foo;
+-------+
| x - y |
+-------+
| 50709 |
+-------+
1 row in set (0.00 sec)
Note how the result is NOT a time value, it's an integer. It happens to be a direct time->string->numeric conversion of 05:07:09, which is the literal as-expected time difference of the two values. But since you're doing MATH, i.e. subtraction, MySQL is assuming you want a numeric answer, and giving it to you.
That's why there's timediff() and similar date/time functions, which return a real date/datetime value, not this wonky/useless integer.
Related
I've been trying to save the product weight in a database field table with the type of decimal.
My code:
$p = Product::find($id)->update([
'weight' => $product['weight'] ? floatval($product['weight']) : null,
]);
It always rounds up the number for some reason, even though dd(floatval($product['weight'])) outputs the correct value, when i try to save it it doesn't save the correct value, only changing the field to the type of float works, but i read that it is not a correct approach.
I'm using MySQL and the Laravel 8.75.
Decimal type in MySQL has two tuning knobs: precision and scale. You omitted the scale, so it defaults to 0.
Documentation (link)
The declaration syntax for a DECIMAL column is DECIMAL(M,D). The ranges of values for the arguments in MySQL 5.1 are as follows:
M is the maximum number of digits (the precision). It has a range of 1 to 65. (Older versions of MySQL permitted a range of 1 to 254.)
D is the number of digits to the right of the decimal point (the scale). It has a range of 0 to 30 and must be no larger than M.
Example
mysql> create table test01 (field01 decimal(9));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test01 (field01) values (123.456);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from test01;
+---------+
| field01 |
+---------+
| 123 |
+---------+
1 row in set (0.00 sec)
mysql> create table test02 (field01 decimal(9, 4));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test02 (field01) values (123.456);
Query OK, 1 row affected (0.01 sec)
mysql> select * from test02;
+----------+
| field01 |
+----------+
| 123.4560 |
+----------+
1 row in set (0.00 sec)
Probably modifying the column with a migration
Schema::table('products', function (Blueprint $table) {
$table->decimal('weight', 9, 4)->change();
});
Documentation
I want to convert this format of datetime "31-12-2018 19:30 hs." from Argentina to an UTC timestamp, I am using the following code:
$clean_date = substr($date, 0, -4);
$dt = new DateTime($clean_date, new DateTimeZone('America/Argentina/Buenos_Aires'));
$dt->setTimeZone(new DateTimeZone('UTC'));
$timestamp = $dt->getTimestamp();
But it doesn't work, in the database the record is "0000-00-00 00:00:00", but if I echo the $dt, till there is working perfectly and showing the datetime in UTC.
Could someone please help me?
Thanks.
This has nothing to do with PHP. You're simply using the incorrect date literal format in MySQL. A per the docs:
MySQL recognizes DATETIME and TIMESTAMP values in these formats:
As a string in either 'YYYY-MM-DD HH:MM:SS' or 'YY-MM-DD HH:MM:SS' format. A “relaxed” syntax is permitted here, too: Any
punctuation character may be used as the delimiter between date parts
or time parts.
As a string with no delimiters in either 'YYYYMMDDHHMMSS' or 'YYMMDDHHMMSS' format, provided that the string makes sense as a
date.
As a number in either YYYYMMDDHHMMSS or YYMMDDHHMMSS format, provided that the number makes sense as a date.
1546335960 could be the last case but numbers don't make sense as date because year 1546 did not have 33 months.
To make it worse, many MySQL Servers are configured by default to let these kind of errors slip through:
mysql> CREATE TABLE test (
-> foo TIMESTAMP
-> );
Query OK, 0 rows affected (0.74 sec)
mysql> SET ##SESSION.sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO test (foo) VALUES (1546335960);
Query OK, 1 row affected, 1 warning (0.39 sec)
mysql> SHOW WARNINGS;
+---------+------+------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'foo' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM test;
+---------------------+
| foo |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)
As you can see, you got a mere warning (that you need to read explicitly) and data corruption.
If you configure your app to use a strict mode you'll get a proper error message just in time:
mysql> SET ##SESSION.sql_mode = 'TRADITIONAL,NO_AUTO_VALUE_ON_ZERO';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO test (foo) VALUES (1546335960);
ERROR 1292 (22007): Incorrect datetime value: '1546335960' for column 'foo' at row 1
mysql>
Please note that timestamp is just a generic English word:
A digital record of the time of occurrence of a particular event.
It isn't necessarily synonym for Unix time.
I have a BLOB field in a MySQL database that contains a seven bit binary field - in essence, one bit for each day of the week, starting on a Sunday with the right hand bit.
I have two records, on one the binary field (called Flags) is set to 0101000 while the other is set to 0000010. I use Querious software on a Mac for database work, and that shows that the field does contain binary data and confirms the above entries.
However, when I issue a SELECT statement, that includes Flags & 8 = 8 in the WHERE statement, both records are returned, yet I believe only the first should be.
The PHP code using bindec($data->flags) & 8 correctly only marks the first record as having the 4th bit (i.e. value 8) set.
Can anyone advise what I'm doing wrong with the MySQL statement - i've been looking at this for over 36 hours now, and just cant see it.
Seems to work in fine here here (on v5.7.13)
mysql> create table z (x bit(7));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into z (x) values (0b0101000), (0b000010);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select cast(x & 8 as unsigned) from z;
+-------------------------+
| cast(x & 8 as unsigned) |
+-------------------------+
| 8 |
| 0 |
+-------------------------+
2 rows in set (0.00 sec)
mysql> select x, cast(x as unsigned) from z where x & 8;
+------+---------------------+
| x | cast(x as unsigned) |
+------+---------------------+
| ( | 40 |
+------+---------------------+
1 row in set (0.00 sec)
You should show your ACTUAL query.
I have a column of type integer with length 10:
`some_number` int(10) unsigned NOT NULL
Into this column I insert a number that is too long:
$some_number = 715988985123857;
$query = "INSERT INTO this_table SET some_number = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param('i', $some_number);
$stmt->execute();
When I look at what is in the table, the number is now:
2147483647
How and why did 715988985123857turn into 2147483647?
Why didn't it get truncated?
What is the mechanism behind this transformation, and can the resulting number be calculated with some formula?
I'm not looking for a solution. I just want to understand the specific number.
http://dev.mysql.com/doc/refman/5.0/en/integer-types.html
The integer overflow will set the max allowed number in the DB as
2147483647
So you need bigint datatype for storing bigger integer
How and why did 715988985123857turn into 2147483647?
Why didn't it get truncated?
What is the mechanism behind this transformation, and can the resulting number be calculated with some formula?
The behavior depends on MySQL Strict SQL Mode setting:
Strict mode controls how MySQL handles invalid or missing values in data-change statements such as INSERT or UPDATE.
There is a chapter in MySQL manual explaining how MySQL handles out-of-range values: Out-of-Range and Overflow Handling:
[...] If no restrictive modes are enabled, MySQL clips the value to the appropriate endpoint of the range and stores the resulting value instead.
In case of Integer Type, the maximum value is:
2147483647 for signed type
4294967295 for unsigned type
Since your query did not throw error, but instead, the column got updated with max allowed value, you can assume that Strict SQL Mode is not enabled on your server. You can verify that by running:
SELECT ##GLOBAL.sql_mode;
SELECT ##SESSION.sql_mode;
None of them will contain STRICT_TRANS_TABLES nor STRICT_ALL_TABLES values (more about the values in MySQL man: sql_mode).
Take this example to test the different behaviors between modes:
mysql> create table test_sql_mode(id int);
mysql> set sql_mode = 'STRICT_TRANS_TABLES';
mysql> SELECT ##SESSION.sql_mode;
+---------------------+
| ##SESSION.sql_mode |
+---------------------+
| STRICT_TRANS_TABLES |
+---------------------+
1 row in set (0.00 sec)
mysql> insert into test_sql_mode(id) value(123456789123456789);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
mysql> select * from test_sql_mode;
Empty set (0.00 sec)
mysql> set sql_mode = '';
mysql> SELECT ##SESSION.sql_mode;
+--------------------+
| ##SESSION.sql_mode |
+--------------------+
| |
+--------------------+
1 row in set (0.00 sec)
mysql> insert into test_sql_mode(id) value(123456789123456789);
Query OK, 1 row affected, 1 warning (0.05 sec)
mysql> show warnings;
+-------+------+---------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------+
| Error | 1264 | Out of range value for column 'id' at row 1 |
+-------+------+---------------------------------------------+
mysql> select * from test_sql_mode;
+------------+
| id |
+------------+
| 2147483647 |
+------------+
1 row in set (0.00 sec)
In short, with strict mode out-of-range value produces an error, without - the value gets adjusted to the allowed limit and a warning is produced.
As for this question:
can the resulting number be calculated with some formula?
I'm not aware of any simple and pure MySQL formula. You would have to check the data type and length:
select data_type, numeric_precision, numeric_scale
from information_schema.columns
where table_schema = "test_database"
and table_name = "test_sql_mode"
and column_name = "id"
...and based on that determine allowed limit.
Non-sql? Data validation (server- and client-side) is the solution.
Well as far as i know, it doesn't have anything to do with PHP, bcx.
If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead.
Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.
So it will be the functionality of SQL which changes the value.
I have a table in MySQL with a field that is decimal, length 9, unsigned. I'm using it for prices.
After I insert the data, and query for it, it has all been rounded and the decimal has been removed.
I'm confused as to why.
Troubleshooting tips?
Host: web.com
phpMyAdmin version: 2.11.10.1
MySQL client version: 5.0.95
Decimal type in MySQL has two tuning knobs: precision and scale. You omitted the scale, so it defaults to 0.
Documentation (link)
The declaration syntax for a DECIMAL column is DECIMAL(M,D). The ranges of values for the arguments in MySQL 5.1 are as follows:
M is the maximum number of digits (the precision). It has a range of 1 to 65. (Older versions of MySQL permitted a range of 1 to 254.)
D is the number of digits to the right of the decimal point (the scale). It has a range of 0 to 30 and must be no larger than M.
Example
mysql> create table test01 (field01 decimal(9));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test01 (field01) values (123.456);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from test01;
+---------+
| field01 |
+---------+
| 123 |
+---------+
1 row in set (0.00 sec)
mysql> create table test02 (field01 decimal(9, 4));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test02 (field01) values (123.456);
Query OK, 1 row affected (0.01 sec)
mysql> select * from test02;
+----------+
| field01 |
+----------+
| 123.4560 |
+----------+
1 row in set (0.00 sec)
I had the same problem. Turns out PHPMyAdmin ignores the decimal place if you enter and assumes it to be 0.
Use alter table query to change it.
ALTER TABLE tablename CHANGE rate rate DECIMAL(30,3) UNSIGNED NOT NULL;
THe rounding is done because may be you have set its datatype as int.
Change its datatype to double OR Float.
This will help you out.
EDIT
If you are having datatype decimal give its size like this edit.
create table numbers (a decimal(10,2));
The rounding is happening because you need to declare the precision in the type declaration
create table test01 (field01 decimal(9,2));
In PHP/MySQLAdmin go to the Structure of the table, hit change and then set the length (which defaults to 10,0) to 10,2 for financial data (dollars).