Incorrect Timezone result rectified via column in MySQL? - mysql

I have a MYSQL database that is on a remote shared server.
One of my columns in a table requires to populate automatically with the CURRENT_TIMESTAMP when the record is being populated with other data.
The database uses the SYSTEM time which is "UTC +00:00", but I need this to be "UTC +01:00"
I cannot use "SET GLOBAL time_zone = '+01:00';" as I don't have the priveliges (understandably), and understand there's no way to set a time_zone just at database level (beyond a session instance, this solution needs stick).
Is there a way that I can have my column populate with "CURRENT_TIMESTAMP + ADD ONE HOUR", like a calculation? As I'm looking for a solution at DB level to this.
I'm not db profficient, but appreciate any advice.

you can create a trigger that launched each time you insert in that column
DELIMITER $$
CREATE TRIGGER update_count
AFTER UPDATE ON table_name (time)
UPDATE table_name
SET HOUR(column_name) = SEC_TO_TIME((UNIX_TIMESTAMP(HOUR(column_name))+1)*60)
WHERE time= NEW.time;
END;
$$DELIMITER ;

Look for the function CONVERT_TZ
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
-> '2004-01-01 13:00:00'
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
-> '2004-01-01 22:00:00'
It might be of help to what you need, here's the docs:
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_convert-tz

You will only change time zone,
Example:
CREATE TABLE IF NOT EXISTS test_timestamp (
t1 TIMESTAMP
);
SET time_zone='+00:00';
INSERT INTO test_timestamp
VALUES('2008-01-01 00:00:01');
SELECT
t1
FROM
test_timestamp;
t1='2008-01-01 00:00:01'
SET time_zone ='+03:00';
SELECT t1
FROM test_timestamp;
t1='2008-01-01 03:00:01'

Related

MySQL delete from database where

Within my database, I have a large number of tables which contain dates. These are expiry dates to be precise.
Currently, I perform the following commands to remove any rows which are older than a specified date using:
DELETE FROM tablename WHERE DATE(datepoint) < '2019-03-18'
1) Is there a way I can instead search and delete from an entire database instead of manually changing the table name and running the command each time?
You could use a PHP function, Anyway I wouldn't recommend deleting any records, just filter your queries for the last 3 months only
Perhaps consider having expiry dates in their own table EXPIRY_DATES. It sounds like it could be an important concept in your domain. Then have your other tables point to the correct expiry date using a foreign key. Using on delete cascade rules from EXPIRY_DATES would clean out records from all child tables when you delete one expiry date from EXPIRY_DATES.
you shoould use procedure (or function):
Define a procedure :
mysql> CREATE PROCEDURE delete_from_table(OUT table_name char(20))
-> BEGIN
-> delete from table_name WHERE DATE(datepoint) < '2019-03-18';
-> END//
mysql> delimiter ;
CALL procedure :
mysql> CALL delete_from_table(#table1);
mysql> CALL delete_from_table(#table2);
mysql> CALL delete_from_table(#table3);

How to insert local time with mysql trigger

Have a shared server and running a mysql trigger in which time is being inserted into a column as follows -
Insert INTO mytable SET time=now();
The table and the column time then gets a GMT time.
I want that local time is inserted into that table and column.
Tried this code but still giving GMT time on insertion -
set #localtime = CONVERT_TZ('now()','GMT','+5:30');
Insert INTO mytable SET time=#localtime;
The column time has settings of TIMESTAMP as default and if I change the settings to Varchar, it gives error - "#1048 - Column 'time' cannot be null"
Please help.
I found answer to this question -
set #localtime = (SELECT CONVERT_TZ('now()','##session.time_zone','+5:30'));
Insert INTO mytable SET time=#localtime;

SQL CHANGE DATE FORMAT IN BULK

I have a database with several hundred fields but my data structure is wrong. It is currently in uk format as follows:
d/m /y
01/01/85
01/01/96
23/12/87
What would be the most efficient way to change the dates in bulk to sql standard of year/month/day
eg.
02/01/85 --> 1985/01/02
Create a new DATE type column in your table:
ALTER TABLE myTable ADD newColumn DATE;
Use MySQL's STR_TO_DATE() function to parse the existing values into your new column:
UPDATE myTable SET newColumn = STR_TO_DATE(oldColumn, '%d/%m/%y');
Change your codebase to use the new column. If this can't happen immediately, you could define BEFORE INSERT and BEFORE UPDATE triggers to keep the new column consistent with the old one:
CREATE TRIGGER myTable_bi BEFORE INSERT ON myTable FOR EACH ROW
SET NEW.newColumn = STR_TO_DATE(oldColumn, '%d/%m/%y');
CREATE TRIGGER myTable_bu BEFORE UPDATE ON myTable FOR EACH ROW
SET NEW.newColumn = STR_TO_DATE(oldColumn, '%d/%m/%y');
Drop the old column:
ALTER TABLE myTable DROP oldColumn;
select date_format(date, '%Y-%m-%d') use this to change it to required format.I have used date_format function. You can get more information about date_format here

Timestamp for row creation and last modification

I need to keep track of the time a row was inserted into the database, and the time it was last modified.
I tried to create two separate columns, and use CURRENT_TIMESTAMP:
create table def (
id int,
creation timestamp
default CURRENT_TIMESTAMP,
modification timestamp
on update CURRENT_TIMESTAMP
);
However, this produced an error:
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
What is the best way to do this?
I'm thinking stored procedure, but looking for a standard solution. I'm also concerned with access privileges -- as few programs/things should be able to touch the timestamps as possible.
Although I would prefer MySQL answers, solutions for other RDBMS's are also appreciated!
Ya this is a lame limitation on MySQL. If you are going through an application you can add a time() call for the created_at column, and let the updated_at column use the CURRENT_TIMESTAMP.
$sql = "INSERT INTO my_table SET name = 'Mike', created_at = " . time();
I'd opt to do this on the created_at column as it probably won't be touched as often as the updated_at column.
-- Edit --
Better yet, use MySQL's built in now() function. This way you only need to be concerned with the timezone of the mysql server, and not the timezones of the app server AND the mysql server.
$sql = "INSERT INTO my_table SET name = 'Mike', created_at = NOW()";
You can use a trigger. The application can also set the value, but if do, it will be overwritten by the database.
delimiter //
CREATE TRIGGER def_bef_update BEFORE UPDATE ON def FOR EACH ROW BEGIN
SET NEW.modification = CURRENT_TIMESTAMP;
END//
delimiter ;
You can also use it to check the data and update your modification date only if has important changes.

Using MySQL variables in a query

I am trying to use this MySQL query:
SET #a:=0; UPDATE tbl SET sortId=#a:=#a+1 ORDER BY sortId;
Unfortunately I get this error:
"Parameter '#a' must be defined"
Is it possible to batch commands into 1 query like this, or do I need to create a stored procedure for this?
You placed the variable assignment in a wrong place:
SET #a:=0; UPDATE tbl SET #a:=sortId=#a+1 ORDER BY sortId;
I think you need a stored procedure for any kind of statefullness. Is there a reason you have been reluctant to create one?
Also how are you running this code? Is it in an editor like SQL Server Manager or as a string in a program?
Your query works fine for me. I tried running it from MySQL Query Browser:
CREATE TABLE tbl (Id INT NOT NULL, SortId INT NOT NULL);
INSERT INTO tbl (Id, SortId) VALUES (1, 9), (2, 22), (3, 13);
SET #a:=0;
UPDATE tbl SET sortId=#a:=#a+1 ORDER BY sortId;
SELECT * From tbl;
Result:
Id sortId
1 1
2 3
3 2
Note that when running queries from MySQL Query Browser should enter one query per line, not two on one line as you are doing. If you want to put this in a stored procedure (probably a good idea) you can create it like this:
DELIMITER //
CREATE PROCEDURE updateSortIds()
BEGIN
SET #a:=0;
UPDATE tbl SET SortId=#a:=#a+1 ORDER BY SortId;
END //
DELIMITER ;
And to execute it, use this:
CALL updateSortIds();