MySQL GENERATED ALWAYS AS ... VIRTUAL syntax error on import - mysql

Trying to import table from backup to another server and getting error in SQL syntax
CREATE TABLE IF NOT EXISTS `book` (
`bid` bigint(20) NOT NULL AUTO_INCREMENT,
`bookdate` datetime NOT NULL,
`create_date` datetime NOT NULL,
`bookdate_date` date GENERATED ALWAYS AS (cast(`bookdate` as date)) VIRTUAL,
`create_date_date` date GENERATED ALWAYS AS (cast(`create_date` as date)) VIRTUAL,
PRIMARY KEY (`bid`),
KEY `IDX_book_bookdate_date` (`bookdate_date`),
KEY `IDX_book_create_date_date` (`create_date_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=316;
phpMyAminError
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GENERATED ALWAYS AS (cast(`bookdate` as date)) VIRTUAL,
`create_date_date` da' at line 5
How do i fix import error? I dont know what this means its beyond my paygrade
`bookdate_date` date GENERATED ALWAYS AS (cast(`bookdate` as date)) VIRTUAL,
`create_date_date` date GENERATED ALWAYS AS (cast(`create_date` as date)) VIRTUAL,

Those are generated columns. They are set automatically, so you cannot assign values in an insert or update. These were introduced in some version of MySQL 5.7, so older versions do not support them. You can replace the idea using views, for similar functionality.
They are calculated -- using the expression -- when the table is queried. This is convenient, because the value is always correct. The VIRTUAL means that the column value is not stored in the table.
The alternative to VIRTUAL is STORED. That calculates the value once when the row is inserted or updated. It uses up storage space but can be convenient if the calculation is expensive.
EDIT:
Based on your comment, you have a problem. One method is to create a view but that can be tricky. Assuming that existing code is referencing the columns, your best best is to define the generated columns as regular columns and use triggers (insert and update) to set them.

Related

MySQL (or Mariadb) Expression with DATEDIFF and DATETIME() OR NOW()

What is wrong here?
CREATE TABLE `actionAngebot` (
`createdAt` DATETIME NOT NULL,
`expiryDat` SMALLINT DEFAULT UNSIGNED AS (DATEDIFF(`createdAt`, DATETIME())) STORED
)
ENGINE=MyISAM;
SQL Error (1064): You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near '() )) STORED ) ENGINE=MyISAM' at line 3 *
please do not propose me this :
CREATE TABLE `promos` (
`createdAt` DATETIME NOT NULL,
`createdTil` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`expiryDateOfReward` SMALLINT(10) AS ((to_days(`createdAt`) - to_days(`createdTil`))) VIRTUAL
)
ENGINE=MyISAM;
I want to make it with 2 columns.
The problem with your current query is that DATETIME is a data type, not a function, so you can't call it as one. DATETIME is not valid in that position either, you would need to use NOW() or CURDATE() dependent on whether you wanted a difference to the date and time or just date.
But
You can't use expressions for generated columns which include functions based on system date and time, so you cannot do what you want (see the manual). You could consider creating a view instead:
CREATE VIEW aabot AS
SELECT *, DATEDIFF(`createdAt`, NOW()) AS expiryDat
FROM actionAngebot

Adding new Column with current time in SQL

Im trying to add a new column to my SQL table i want the data type to be TIME and the default value to be CURRENT_TIME. This is my query.
ALTER TABLE tuesday_records ADD cur_time TIME DEFAULT CURRENT_TIME
And this is the error message i get.
Error
SQL query:
ALTER TABLE tuesday_records ADD cur_time TIME DEFAULT CURRENT_TIME
MySQL said: Documentation
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CURRENT_TIME' at line 1
You can do what you want with generated columns:
create table t (
id int auto_increment primary key,
x int,
t timestamp default now(),
tt time generated always as (time(t))
);
That is, add a timestamp column and then extract the time.
Here is a db<>fiddle.
Although this answers your question, I'm not sure if it is the best approach to your overall problem.

How to update date field automatically from a timestamp field in Mysql 5.5?

I have an InnoDB table with a timestamp in it, and I wish to have another field which carries only the date part of the timestamp, so that I can create an index on it. (My temporal queries will always be bound by date, so having an index with high cardinality on the timestamp is not really needed.)
Is it possible to have the date field update automatically ON UPDATE from the timestamp field (similar to how CURRENT_TIMESTAMP works)?
I tried the following but it MySQL says I have an error in my SQL syntax.
CREATE TABLE test_table (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`full_ts` timestamp NULL DEFAULT NULL COMMENT 'The full timestamp',
`only_date` date NULL DEFAULT NULL ON UPDATE date(full_ts) COMMENT 'This field carries only the date part of the full timestamp for better indexing.',
PRIMARY KEY (`id`),
KEY `ONLY_DATE_IDX` (`only_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I could of course update both fields everywhere in the code, but it would be cleaner if the only_date field was a slave of the full_ts field, updated and kept consistent by the database.
I know that in MySQL 5.7.5 there was a new feature added for stored generated columns, which seem to do exactly this. Unfortunately it is not possible to upgrade the database version at the moment.
Is there a way to achieve this in MySQL 5.5?
This will update the "only_date" column when you update the "full_ts" column
CREATE TRIGGER `autoDate` BEFORE UPDATE ON `test_table` FOR EACH ROW BEGIN
SET NEW.only_date=DATE(NEW.full_ts);
END
EDIT:
For further reading on triggers, please refer to https://dev.mysql.com/doc/refman/5.5/en/create-trigger.html
Also worth reading about triggers https://dev.mysql.com/doc/refman/5.5/en/faqs-triggers.html

Convert default column value from datetime to varchar

I have to add a varchar column to a table which defaults to the current timestamp. To do this I somehow need to convert the value from datetime to varchar.
I tried the following
ALTER TABLE `TableName`
CHANGE COLUMN `DocumentID` `DocumentID` VARCHAR(150) NULL DEFAULT CONVERT(NOW(), CHAR);
or
ALTER TABLE `TableName`
CHANGE COLUMN `DocumentID` `DocumentID` VARCHAR(150) NULL DEFAULT CONVERT(CURRENT_TIMESTAMP, CHAR);
I always get an error message, that my syntax is wrong. I am using MariaDB and HeidiSQL. Is there a way to do this?
EDIT: I am basically looking for a MySQL equivalent of the following SQL Server statement:
ALTER TABLE [dbo].[TableName] ADD CONSTRAINT [DF_TableName_DocumentID] DEFAULT (getdate()) FOR [DocumentID]
MariaDB document says
In MariaDB 10.2.1 you can use most functions in DEFAULT. Expressions
should have parentheses around them.
Hence you may check for the version of MariaDB and use the right syntax (parenthesis around expression):
(CONVERT(CURRENT_TIMESTAMP, CHAR))
Update
As an alternative, you may use Trigger to set the function value for the stable releases (< 10.2)
If you use CURRENT_TIMESTAMP as default value, you must use the datatype that the function retrieves, in this case is a timestamp as you can see in the docs.
I don't know the reasons that may lead you to save this as a varchar. I'm not sure but I think that MariaDB doesn't allow to call functions as default values so you can't convert CURRENT_TIMESTAMP as varchar. You have an alternative approach, make an after insert trigger updating the field (you can call CONVERT(CURRENT_TIMESTAMP, VARCHAR) inside a trigger).
Either way, I recomend to stay with timestamp.
I see the field is called "DocumentID", perhaps you want to save a hash value as identifier? You can archieve this with virtual columns. An example.

mysql table default formula

In mysql (Ubuntu 13.10, MySql 5.5) I'm trying to create a table that will automatically create a random alphanumeric ID with this code:
create table YGraph (
YGraphEdgeId CHAR(8) NOT NULL PRIMARY KEY DEFAULT SUBSTRING(MD5(RAND()) FROM 1 FOR 8),
YGraphStartVertex CHAR(6) NOT NULL,
YGraphEndVertex CHAR(6) NOT NULL
);
but phpmyadmin is complaining:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SUBSTRING(MD5(RAND()) FROM 1 FOR 8), YGraphStartVertex CHAR(6) NOT NULL, ' at line 2
. . . and putting quotes around the formula only give a generic
#1067 - Invalid default value for 'YGraphEdgeId'
I simply want a new record creation to run the default formula and stick an 8-place random alphanum in the YGraphEdgeId field. I seem to remember this formula working in an INSERT. What am I doing wrong?
Currently you can't use a function to provide a default value for a column, see https://dev.mysql.com/doc/refman/5.5/en/data-type-defaults.html
As per MySQL Documentation on Data Type Default Values
...the default value must be a constant; it cannot be a function or an expression....
Hence you can't use functions or expressions there.
Secondly, you can assign a default string value but it should abide by the length of the column data-type used. String used to define default value was more that 8 characters. And hence the error thrown.