The below is my table definition that automatically inserts timestamp value into each record. All i want to do is let the timestamp use a specific timezone for example in my case i want it to use the current time of British Columbia How do i do that ?
Because when i insert data in the table i do not really pass a timestame value from my php script but it takes the default value.
CREATE TABLE `cfv_postbusupdate` (
`BusNumber` int(11) NOT NULL,
`Direction` varchar(100) DEFAULT 'Not Provided',
`StopNames` varchar(300) DEFAULT 'Not Provided',
`Status` varchar(45) DEFAULT 'Not Provided',
`comments` varchar(150) DEFAULT 'None',
`username` varchar(45) DEFAULT 'anonymous_user',
`dayofweek` varchar(45) DEFAULT NULL,
`time` varchar(20) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`DatePosted` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
Timestamps are stored as UTC values ad converted on retrieval to the time zone in use by the application. If you want British Columbia time set the time zone with SET time_zone = 'america/vancouver';
The manual reference is here
use this one: refer this link:https://stackoverflow.com/a/6158432/3242978
-- Make sure we're all working off of the same local time zone
test=> SET timezone = 'America/Los_Angeles';
SET
test=> SELECT NOW();
now
-------------------------------
2011-05-27 15:47:58.138995-07
(1 row)
test=> SELECT NOW() AT TIME ZONE 'UTC';
timezone
----------------------------
2011-05-27 22:48:02.235541
(1 row)
update: 1
According to MySQL docs, the error #1193 occurs when you use wrong code for SQLSTATE.
Message: Unknown system variable %s
And, as you can see on the same page, the SQLSTATE 99003 is not defined.
Related
I have a database (MySQL 8.0) with four timestamp columns, using the default timestamp settings, i.e. no fraction of seconds. I would like to start using fractions of a second, probably two decimals, so TIMESTAMP(2). The process that generates the data does not always provide a timestamp to column timestamp_column_3 (just renamed the columns as timestamp_column_1 to timestamp_column_4 here) and thus there are many '0000-00-00 00:00:00' in timestamp_column_3. When I tried converting the
timestamp_column_1 by running the following query:
ALTER TABLE table_name MODIFY COLUMN timestamp_column TIMESTAMP(2);
I get the following response:
Error Code: 1292. Incorrect datetime value: '0000-00-00 00:00:00' for column 'timestamp_column_3' at row 74608.
So, two questions:
Why does timestamp_column_3 interfere with my altering of column timestamp_column_1?
How do I proceed to convert all four columns to datatype TIMESTAMP(2)?
I looked around and found this answer to a similar question. But I'd rather not modify the mode of the database as I'm not very inexperienced and this is a production database. Is there a way to adjust the timestamps in the column to the minimum allowed (I assume this is 1970-01-01 00:00:00). I don't really care about the value. Also, I don't understand why the insertion process is allowed to insert these incorrect values as the mode is the following:
STRICT_TRANS_TABLES,
NO_ZERO_IN_DATE,
NO_ZERO_DATE,
ERROR_FOR_DIVISION_BY_ZERO,
NO_ENGINE_SUBSTITUTION
The incorrect values doesn't really matter as we know they don't "exist" but of course it would be nice to have everything correct. What would then be the "correct" value instead of a ZERO_DATE?
-- EDIT -- Add some information
Version: 8.0.18-google
Table:
CREATE TABLE `event` (
`c1` int(11) DEFAULT NULL,
`c2` varchar(32) NOT NULL,
`c3` varchar(32) NOT NULL,
`c4` varchar(64) NOT NULL,
`c5` varchar(64) NOT NULL,
`c6` varchar(64) NOT NULL,
`c7` varchar(64) NOT NULL,
`c8` varchar(64) NOT NULL,
`c9` varchar(128) DEFAULT NULL,
`timestamp_column_1` timestamp NOT NULL,
`timestamp_column_2` timestamp NOT NULL,
`timestamp_column_3` timestamp NULL DEFAULT NULL,
`timestamp_column_4` timestamp NOT NULL,
PRIMARY KEY (`c4`),
KEY `event-timestamp_column_1` (`timestamp_column_1`),
KEY `event-timestamp_column_3` (`timestamp_column_3`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
0, a, b, c, d, e, f, g, , 2021-02-19 07:45:30, 2021-02-19 07:45:29, 0000-00-00 00:00:00, 2021-06-03 20:11:45
The data is added through Google Storage CSV import function and timestamp_column_3 sometimes has no data in the CSV file, i.e. the column is just represented as ,, in the CSV.
I am trying to create an event in mysql
Schema :
create event alert_2 ON SCHEDULE EVERY 300 SECOND DO
BEGIN
DECLARE current_time DATETIME;
DECLARE attempted INT;
DECLARE completed INT;
DECLARE calc_value DECIMAL;
set #current_time = CONVERT_TZ(NOW(), ##session.time_zone, '+0:00');
select count(uniqueid) as #attempted,SUM(CASE WHEN seconds > 0 THEN 1 ELSE 0 END) as #completed from callinfo where date >= DATE_SUB(#current_time, INTERVAL 300 SECOND) AND date <= #current_time;
SET #calc_value = (ROUND((#completed/#attempted)*100,2);
IF #calc_value <= 10.00 THEN
INSERT INTO report(value1) value (#calc_value);
END IF;
END;
Problem :
Event is not going to creating
Need suggestion :
Is this create any overload on callinfo table ?
If yes,Would you like to suggest any other way to achieve same thing ?
May i create similar but multiple around 50.Will it create huge load on call info table.
Call info schema :
CREATE TABLE `callinfo` (
`uniqueid` varchar(60) NOT NULL DEFAULT '',
`accountid` int(11) DEFAULT '0',
`type` tinyint(1) NOT NULL DEFAULT '0',
`callerid` varchar(120) NOT NULL,
`callednum` varchar(30) NOT NULL DEFAULT '',
`seconds` smallint(6) NOT NULL DEFAULT '0',
`trunk_id` smallint(6) NOT NULL DEFAULT '0',
`trunkip` varchar(15) NOT NULL DEFAULT '',
`callerip` varchar(15) NOT NULL DEFAULT '',
`disposition` varchar(45) NOT NULL DEFAULT '',
`date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`debit` decimal(20,6) NOT NULL DEFAULT '0.000000',
`cost` decimal(20,6) NOT NULL DEFAULT '0.000000',
`provider_id` int(11) NOT NULL DEFAULT '0',
`pricelist_id` smallint(6) NOT NULL DEFAULT '0',
`package_id` int(11) NOT NULL DEFAULT '0',
`pattern` varchar(20) NOT NULL,
`notes` varchar(80) NOT NULL,
`invoiceid` int(11) NOT NULL DEFAULT '0',
`rate_cost` decimal(20,6) NOT NULL DEFAULT '0.000000',
`reseller_id` int(11) NOT NULL DEFAULT '0',
`reseller_code` varchar(20) NOT NULL,
`reseller_code_destination` varchar(80) DEFAULT NULL,
`reseller_cost` decimal(20,6) NOT NULL DEFAULT '0.000000',
`provider_code` varchar(20) NOT NULL,
`provider_code_destination` varchar(80) NOT NULL,
`provider_cost` decimal(20,6) NOT NULL DEFAULT '0.000000',
`provider_call_cost` decimal(20,6) NOT NULL,
`call_direction` enum('outbound','inbound') NOT NULL,
`calltype` enum('STANDARD','DID','FREE','CALLINGCARD') NOT NULL DEFAULT 'STANDARD',
`profile_start_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`answer_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`bridge_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`progress_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`progress_media_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`end_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`billmsec` int(11) NOT NULL DEFAULT '0',
`answermsec` int(11) NOT NULL DEFAULT '0',
`waitmsec` int(11) NOT NULL DEFAULT '0',
`progress_mediamsec` int(11) NOT NULL DEFAULT '0',
`flow_billmsec` int(11) NOT NULL DEFAULT '0',
`is_recording` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0 for On,1 for Off'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='callinfo';
ALTER TABLE `callinfo` ADD UNIQUE KEY `uniqueid` (`uniqueid`), ADD KEY `user_id` (`accountid`);
More Information about callinfo table :
In call info table around 20K/hour rercords are inserted.
Please suggest ,If need to apply any indexing in schema to get good performance.
Some suggestions:
user-defined variables (variables named starting with # character) are separate and distinct from local variables
there's no need to declare local variables that aren't referenced
use local variables in favor of user-defined variables
a column alias (identifier) that starts with # character need to be escaped (or MySQL will throw a syntax error)
assigning a column alias (identifier) that looks like a user-defined variable is just a column alias; it is not a reference to a user-defined variable
use SELECT ... INTO to assign scalar values returned from statement into local variables and/or user-defined variables
declaring datatype DECIMAL is equivalent to specifying DECIMAL(10,0)
in INSERT ... VALUES statement the keyword is VALUES not VALUE
best practice is to give local variables names that are different from column names
best practice is to qualify all column references
its a bit odd to insert only a single column, a calculated value, into a table without some other identifying values (it's not illegal. it may be exactly what the specification calls for. it just strikes me as a bit odd. I bring it up in light of the code as written, because appears that the author of the code is not familiar with MySQL.)
using CONVERT_TZ is a bit odd; given that any datetime value referenced in a SQL statement will be interpreted in the current session time zone; we're kind of assuming that the date column is DATETIME datatype, but that's just a guess.
to create a MySQL stored program that contains semicolons, the DELIMITER for the session needs to be changed to character(s) that don't appear in the stored program definition
Rather than address each individual problem in the stored program, I'm going to suggest a revision that does what it looks like the original code was intended to do:
DELIMITER $$
CREATE EVENT alert_2 ON SCHEDULE EVERY 300 SECOND DO
BEGIN
DECLARE ld_current_time DATETIME;
DECLARE ln_calc_value DECIMAL(20,2);
-- DECLARE li_attempted INT;
-- DECLARE li_completed INT;
SET ld_current_time = CONVERT_TZ(NOW(), ##session.time_zone, '+0:00');
SELECT ROUND( 100.0
* SUM(CASE WHEN c.seconds > 0 THEN 1 ELSE 0 END)
/ COUNT(c.uniqueid)
,2) AS calc_value
-- , COUNT(c.uniqueid) AS attempted
-- , SUM(CASE WHEN c.seconds > 0 THEN 1 ELSE 0 END) AS completed
FROM callinfo c
WHERE c.date > ld_current_time + INTERVAL -300 SECOND
AND c.date <= ld_current_time
INTO ln_calc_value
-- , li_attempted
-- , li_completed
;
IF ln_calc_value <= 10.00 THEN
INSERT INTO report ( value1 ) VALUES ( ln_calc_value );
END IF;
END$$
DELIMITER ;
For performance, we want to have an index with date as the leading column
... ON `callinfo` (`date`, ...)
Ideally (for the query in this stored program) the index with the leading column of date would be a covering index (including all of the columns that are referenced in the query), e.g.
... ON `callinfo` (`date`,`seconds`,`uniqueid`)
Q: Is this create any overload on callinfo table ?
Since this runs a query against callinfo table, it will need to obtain shared locks. With an appropriate index available, and assuming that 5 minutes of call info is a smallish set of rows, I wouldn't expect this query to contribute significantly towards performance problems or contention issues. If it does cause a problem, I would expect that this query in this stored program isn't the root cause of the problem, it will only exacerbate a problem that already exists.
Q: If yes,Would you like to suggest any other way to achieve same thing ?
It's difficult to suggest alternatives to achieving a "thing" when we haven't defined the "thing" we are attempting to achieve.
Q: May i create similar but multiple around 50. Will it create huge load on callinfo table.
A: As long as the query is efficient, is selecting a smallish set of rows via a suitable index, and runs quickly, I wouldn't expect that query to create huge load, no.
FOLLOWUP
For optimal performance, we are definitely going to want an index with leading column of date.
I'd remove the reference to uniqueid in the query. That is, replace COUNT(c.uniqueid) with SUM(1). The results from those are equivalent (given that uniqueid is guaranteed to be non-NULL) except in the case of no rows, COUNT() will return 0 and SUM() will return NULL.
Since we're dividing by that expression, in the case of "no rows" it's a difference between "divide by zero" and "divide by null". And a "divide by zero" operation will raise an error with some settings of sql_mode. If I divide by COUNT(), I'm going to want to convert a zero to NULL before I do the division
... / NULLIF(COUNT(...),0)
or the more ansi standards compliant
... / CASE WHEN COUNT(...) = 0 THEN NULL ELSE COUNT(...) END
but we can avoid that rigmarole by using SUM(1) instead, then we don't have any special handling for the "divide by zero" case. But what that really buys us is that we are removing the reference to the uniqueid column.
Then a "covering index" for the query will require only two columns.
... ON `callinfo` (`date`,`seconds`)
(i.e. EXPLAIN will show "Using index" in the Extra column, and show "range" for access)
Also, I'm not getting my brain wrapped around the need for CONVERT_TZ.
why do i get invalid default value error for the variable "last_updated"?
note i am getting this error while i run the following code in MySQL console in phpmyadmin
CREATE TABLE IF NOT EXISTS `articles` (
`article_id` int(10) NOT NULL AUTO_INCREMENT,
`content_id` int(10) NOT NULL,
`article_body` text NOT NULL,
`last_updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`article_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=532 ;
You need to change the last_updated column's data type to timestamp rather than datetime. This will allow the use of CURRENT_TIMESTAMP as a default value.
As it happens, these two data types are represented in the same format YYYY-MM-DD HH:MM:SS. So if/when you use the data, you shouldn't run into any troubles.
Check your MySQL server version, CURRENT_TIMESTAMP is allowed since version 5.6.5 as DEFAULT for DATETIME type, otherwise you should use either TIMESTAMP type or maintain it outside.
Hi I have a log database table in mysql which captures a start date and time and an end date and time.
The start and now the stop time is inserted to the record.
I have a third field which is duration which I would like displayed as hh:mm:ss
The schema looks like this at present
CREATE TABLE IF NOT EXISTS `log` (
`uid` int(20) NOT NULL AUTO_INCREMENT,
`room` int(11) NOT NULL,
`start` datetime NOT NULL,
`stop` datetime NOT NULL,
`duration` datetime DEFAULT NULL,
`participants` int(3) NOT NULL,
`recorded` varchar(3) NOT NULL,
`rec_file` varchar(35) NOT NULL,
PRIMARY KEY (`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Log File' AUTO_INCREMENT=106 ;
I'm trying to create a trigger which calculates the duration and writes it to the duration field as data is inserted
Currently the trigger I am trying to debug looks like this
BEGIN
SET NEW.duration = (TIMEDIFF (NEW.start,NEW.stop)) ;
END
The result is the duration field remains set to 0000-00-00 00:00:00.000000
Any suggestions on how to make this work are greatfully recived
Try to add the following :
Change duration type to TIME instead of DATETIME. According to documentation, the result returned by TIMEDIFF() is limited to the range allowed for TIME values.
This is the reason you are receiving all zeros currently.
I assume that stop time will always be later than start time, so I would write the trigger in the following way:
CREATE TRIGGER your_schema.insert_duration BEFORE INSERT ON your_schema.log
FOR EACH ROW SET NEW.duration = TIMEDIFF(NEW.stop, NEW.start);
The result will be in HH:MM:SS format for duration field.
I've got a table that looks like this:
CREATE TABLE IF NOT EXISTS `Hosts` (
`id` int(128) NOT NULL AUTO_INCREMENT,
`IP` varchar(15) NOT NULL DEFAULT '',
`Port` varchar(5) NOT NULL DEFAULT '',
`Password` varchar(32) NOT NULL DEFAULT '',
`Username` varchar(32) NOT NULL DEFAULT '',
`Tid` varchar(32) NOT NULL DEFAULT '',
`EquipType` varchar(64) NOT NULL DEFAULT '',
`Version` varchar(128) DEFAULT NULL,
`Status` varchar(10) NOT NULL DEFAULT '',
`Location` varchar(128) NOT NULL DEFAULT '',
`Lastconnection` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
`Lastbackup` date NOT NULL DEFAULT '0000-00-00',
`Backupstatus` varchar(64) NOT NULL DEFAULT '',
`Backupmsg` text,
`Backupfile` varchar(30) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `IP` (`IP`),
KEY `Tid` (`Tid`),
KEY `EquipType` (`EquipType`),
KEY `Status` (`Status`),
KEY `Lastbackup` (`Lastbackup`),
KEY `Backupstatus` (`Backupstatus`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=716 ;
In my mind, this means that any time a row is updated, the field 'Lastconnection' should be stamped with the current timestamp. However, when I run something like:
update Hosts set Backupstatus = 'FAIL', Backupmsg = 'Connection timed out' where Tid = 'SITE001'
Lastconnection stays '0000-00-00 00:00:00'. There's either a database issue I'm not seeing, or I'm completely misunderstanding the 'ON UPDATE CURRENT_TIMESTAMP' clause.
Have you tried to use null for that field when updating?
You could also try setting default value to CURRENT_TIMESTAMP, rather than 0000-00-00 00:00:00.
Nevertheless, whenever I want to have creation and update time I always use the following:
...
CREATED timestamp NOT NULL default '0000-00-00 00:00:00',
UPDATED timestamp NOT NULL default now() on update now(),
....
I use now(), because is an alias for CURRENT_TIMESTAMP and it is shorter. At the end, table structure gets CURRENT_TIMESTAMP, so don't worry.
The trick with CREATED field is to remember to use null on both fields for INSERT statements, for UPDATE statements it is not required:
INSERT INTO mytable (field1, field2, created, updated)
VALUES ('foo', 'bar', null, null);
It might be the case that the update statement doesn't change anything. If the row with Tid = 'SITE001' already has Backupstatus set to 'FAIL' and Backupmsg set to 'Connection timed out' (maybe, set by some previous backup attempt), then MySQL will skip this row and therefore won't change the Lastconnection timestamp.
Also, I see ON UPDATE CURRENT_TIMESTAMP more like an administrative feature to keep track of data changes. As a programmer, I would add the timestamp update explicitly:
update Hosts
set Backupstatus = 'FAIL', Backupmsg = 'Connection timed out', Lastconnection = NOW()
where Tid = 'SITE001'.
You must remember that if no value was changed on update it won't set the current time stamp,
You have to set the value in query NOW() to set for the current time stamp !!!
update Hosts set Backupstatus = 'FAIL',Lastconnection = NOW() , Backupmsg = 'Connection timed out' where Tid = 'SITE001'
Remember the value must change in order for the current time stamp to change.
To specify automatic properties, use the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses. The order of the clauses does not matter. If both are present in a column definition, either can occur first. Any of the synonyms for CURRENT_TIMESTAMP have the same meaning as CURRENT_TIMESTAMP. These are CURRENT_TIMESTAMP(), NOW(), LOCALTIME, LOCALTIME(), LOCALTIMESTAMP, and LOCALTIMESTAMP().
Use of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP is specific to TIMESTAMP. The DEFAULT clause also can be used to specify a constant (nonautomatic) default value; for example, DEFAULT 0 or DEFAULT '2000-01-01 00:00:00'.
DEFAULT 0 do not work if the NO_ZERO_DATE SQL mode is enabled because that mode causes “zero” date values (specified, for example, as 0 '0000-00-00 00:00:00') to be rejected. Be aware that the TRADITIONAL SQL mode includes NO_ZERO_DATE.
In addition, you can initialize or update any TIMESTAMP column to the current date and time by assigning it a NULL value, unless it has been defined with the NULL attribute to permit NULL values.
If you want the record to automatically update the timestamp whenever the record is changed, here's the four simple steps you need to accomplish (could be all in one step, depending on if you're using command line or GUI to administer):
Create field to hold auto-updated timestamp (I typically call mine 'modified').
Specify field Type as 'TIMESTAMP'
Specify field Default as 'CURRENT_TIMESTAMP'
Specify field Extra as 'ON UPDATE CURRENT_TIMESTAMP'
Now the field that contains your timestamp will always be updated to the current timestamp anytime the record is updated.