Laravel 7 - weird timestamp migration behavior - mysql

I'm creating a table via a migration file.
I have multiple timestamp columns which one of is not supposed to be nullable.
If i set that one column first in order the migration goes through just fine, if I place any nullable timestamp column before it, the migration fails with an exception:
SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'credit_date' (SQL: create table `feedback_survey_records` (`id` bigint unsigned not null auto_increment primary key, `user_id` bigint unsigned not null, `feedback_survey_id` bigint unsigned not null, `reward` smallint not null, `credit_status` varchar(45) null, `answer_date` timestamp null, `open_date` timestamp null, `credit_date` timestamp not null, `decline_date` timestamp null, `decline_reason` varchar(255) null, `response_id` varchar(255) null, `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci' engine = innodb)
Successful migration
$table->timestamp('credit_date');
$table->timestamp('answer_date')->nullable();
$table->timestamp('open_date')->nullable();
$table->timestamp('decline_date')->nullable();
Failing migration
$table->timestamp('answer_date')->nullable();
$table->timestamp('open_date')->nullable();
$table->timestamp('credit_date');
$table->timestamp('decline_date')->nullable();
I looked at the database and noticed that laravel automatically added a default value and extra instructions on the successful migration
Database structure Image
Can someone please shed some light on why this might be happening?

Related

Mysql automated date field, syntax errors

I'm trying to create a mysql table which contains two fields that are automatically given the current date when data is first put into them
CREATE TABLE IF NOT EXISTS `database`.`characters` (
`character_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`ckey` VARCHAR(30) NOT NULL,
`character_name` VARCHAR(26) NOT NULL,
`birth` DATE NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_seen` DATE NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`character_id`),
UNIQUE INDEX `character_id_UNIQUE` (`character_id` ASC) VISIBLE)
this is not working, i get invalid default value error, which is progress
Everything else i've tried throws error 1064, sql syntax
In place of current timestamp I have tried...
GET_DATE()
GET_DATE
GETDATE
CURDATE
CURDATE()
CURRENT_DATE
CURRENT_DATE()
All of these are throwing the same syntax error, there is no error if i remove the default value.
I am almost entirely clueless about database code, this is a real newbie project, any help would be appreciated
Use datetime instead of date.
CREATE TABLE IF NOT EXISTS `characters` (
`character_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`ckey` VARCHAR(30) NOT NULL,
`character_name` VARCHAR(26) NOT NULL,
`birth` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_seen` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`character_id`),
UNIQUE INDEX `character_id_UNIQUE` (`character_id` ASC) VISIBLE)

MySQL Create Table 'closing parenthesis'

This is my sql query for MySQL:
DROP DATABASE IF EXISTS java_proj;
CREATE DATABASE java_proj
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
USE java_proj;
CREATE TABLE Konto(
idKonto SERIAL PRIMARY KEY,
login VARCHAR(14) UNIQUE CHECK(LENGTH(login)>4) NOT NULL,
haslo VARCHAR(14) CHECK(LENGTH(haslo)>4) NOT NULL,
data_rejestracji DATE DEFAULT NOW() NOT NULL,
data_urodzenia DATE NOT NULL,
imie VARCHAR(30) NOT NULL,
nazwisko VARCHAR(30) NOT NULL
);
I'm getting error out of nowhere, in the line of login.
Error: Syntax error: 'closing parenthesis'
As mentioned in comments MySQL doesn't support CHECK.
But you also have another problem with that query: the DATE field cannot have NOW() as DEFAULT value, you can change it in DATETIME and set CURRENT_TIMESTAMP as default value
Cleaned up your query should probably look like this
CREATE TABLE Konto(
idKonto SERIAL PRIMARY KEY,
login VARCHAR(14) UNIQUE NOT NULL,
haslo VARCHAR(14) NOT NULL,
data_rejestracji DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
data_urodzenia DATE NOT NULL,
imie VARCHAR(30) NOT NULL,
nazwisko VARCHAR(30) NOT NULL
);
You can read about some workaround to the use instead of CHECK at this link
CHECK constraint in MySQL is not working

Solving error "Expression of generated column 'registrationno' contains a disallowed function"

Can someone tell me the right way of doing an generated column in mysql.
im supposed to generate a registration_no in format:
SVSRYYYYinvoice_no
yyyy-> year
I have been using MYSQL workbench to create my db but i'm getting this error
ERROR 3102: Expression of generated column 'registrationno' contains a disallowed function.
SQL Statement:>CREATE TABLE `invoicegeneration`.`registration` (
`invoice_no` SMALLINT(4) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
`amount` INT(11) NULL,
`name` VARCHAR(45) NOT NULL,
`invoice_date` DATETIME NULL,
`amt_in_words` VARCHAR(45) NULL,
`mop` VARCHAR(45) NULL,
`registrationcol` VARCHAR(45) NULL,
`dated` VARCHAR(45) NULL,
`drawn_on` VARCHAR(45) NULL,
`course` VARCHAR(45) NOT NULL,
`towards` VARCHAR(45) NULL,
`duration` VARCHAR(45) NULL,
`registrationno` VARCHAR(45) GENERATED ALWAYS AS
(CONCAT('SVSR',YEAR(CURDATE()),invoice_no)) STORED,
PRIMARY KEY (`invoice_no`),
UNIQUE INDEX `invoice_no_UNIQUE` (`invoice_no` ASC))
Can someone show me the right way to create the generated column
The problem is that you cannot create a virtual column based on non-deterministic function, as that would cause problems during replication.
See the “Limitations section in this blog post for more details.
You already have the invoice_date column, so a better solution would be to replace the column definition for registrationno with something like:
registrationno VARCHAR(45) GENERATED ALWAYS AS (CONCAT('SVSR',YEAR(invoice_date),invoice_no)) STORED
As a further optimization you could store the year of the invoice_date as a stand-alone column. This would allow you to place an index on it and then do analysis by year, or partition the table by year if your data grows huge.

MySQL CURRENT_TIMESTAMP Error Parsing DDL for microseconds

This is the MySQL table that I want, but focus on datum_en_tijd:
CREATE TABLE `navigatie` (
`navigatie_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`navigatie_id`),
`huidige_vraaggroep` varchar(255) NOT NULL,
`vorige_vraaggroep` varchar(255) DEFAULT NULL,
`richting` varchar(255) NOT NULL,
`datum_en_tijd` timestamp(3) NOT NULL,
`schadegeval_id` bigint(20) UNSIGNED DEFAULT NULL,
`claim_id` bigint(20) UNSIGNED DEFAULT NULL,
`gebruiker_id` bigint(20) NOT NULL,
`soort_gebruiker` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
As you can see TIMESTAMP is with (3) for milliseconds
Whenever I try to Alter Table... in MySQL Workbench I get this error:
When I do View DDL, I get a new tab with this query:
delimiter $$
CREATE TABLE `navigatie` (
`navigatie_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`huidige_vraaggroep` varchar(255) NOT NULL,
`vorige_vraaggroep` varchar(255) DEFAULT NULL,
`richting` varchar(255) NOT NULL,
`datum_en_tijd` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
`schadegeval_id` bigint(20) unsigned DEFAULT NULL,
`claim_id` bigint(20) unsigned DEFAULT NULL,
`gebruiker_id` bigint(20) NOT NULL,
`soort_gebruiker` varchar(255) NOT NULL,
PRIMARY KEY (`navigatie_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
Note the change on
`datum_en_tijd` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
Is this a bug or what?
Also note the SYNTAX ERROR on line 8 MySQL WorkBench gives us:
I'm running MySQL 5.6.16
Incompatible change: In very old versions of MySQL (prior to 4.1), the
TIMESTAMP data type supported a display width, which was silently
ignored beginning with MySQL 4.1. This is deprecated in MySQL 5.1, and
removed altogether in MySQL 5.5. These changes in behavior can lead to
two problem scenarios when trying to use TIMESTAMP(N) columns with a
MySQL 5.5 or later server:
When importing a dump file (for example, one created using mysqldump) created in a MySQL 5.0 or earlier server into a server from
a newer release series, a CREATE TABLE or ALTER TABLE statement
containing TIMESTAMP(N) causes the import to fail with a syntax error.
To fix this problem, edit the dump file in a text editor to replace any instances of TIMESTAMP(N) with TIMESTAMP prior to
importing the file. Be sure to use a plain text editor for this, and
not a word processor; otherwise, the result is almost certain to be
unusable for importing into the MySQL server.
http://dev.mysql.com/doc/refman/5.1/en/timestamp-initialization.html
So you cant have
`datum_en_tijd` timestamp(3)
instead you need to use
`datum_en_tijd` timestamp
or
`datum_en_tijd` datetime(3)
Yes timestamp does not require this any more, i usually just use it with either DEAFAULT or ON UPDATE CURRENT_TIMESTAMP, you may find either useful.
Some variants to pick from:
created_at timestamp(3) NOT NULL DEFAULT '1970-01-01 12:34:56'
mysql_row_created_at timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
created_at timestamp(3) NULL DEFAULT NULL
Each has its own pluses and minuses.
Don't (ever) use datetime, as that has no related timezone, it is mostly just liike a (packed) string.
The MySQL timestamp type is physically stored in UTC (it is a UNIX-epoch delta). It is rendered in the active timezone of the session.

create table error in mysql. 1071 error

hi all can some one plz help me,
while creating table in mysql i am getting the following error
MySQL error 1071: Specified key was too long; max key length is 767 bytes
my table definition is as follows.
CREATE TABLE oauth_consumer (id char(36) NOT NULL ,
name varchar(255) NULL ,
date_entered datetime NULL ,
date_modified datetime NULL ,
modified_user_id char(36) NULL ,
created_by char(36) NULL ,
description text NULL ,
deleted bool DEFAULT '0' NULL ,
assigned_user_id char(36) NULL ,
c_key varchar(255) NULL ,
c_secret varchar(255) NULL,
PRIMARY KEY (id),
UNIQUE ckey (c_key)
);
No problem in your query. May be you are running old version of MySql. Use new version. If you are using new version try to use following query to create table
CREATE TABLE `oauth_consumer` (
`id` CHAR(36) NOT NULL,
`name` VARCHAR(255) NULL DEFAULT NULL,
`date_entered` DATETIME NULL DEFAULT NULL,
`date_modified` DATETIME NULL DEFAULT NULL,
`modified_user_id` CHAR(36) NULL DEFAULT NULL,
`created_by` CHAR(36) NULL DEFAULT NULL,
`description` TEXT NULL,
`deleted` TINYINT(1) NULL DEFAULT '0',
`assigned_user_id` CHAR(36) NULL DEFAULT NULL,
`c_key` VARCHAR(255) NULL DEFAULT NULL,
`c_secret` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `ckey` (`c_key`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;
First of all, your database character set is most likely set to utf8, so your 255 characters get blown up to 765 characters; though close, that's not greater than the imposed limit of 767, but it gives an idea of why you're hitting that limit nonetheless.
Regardless, it's not recommended to use such a wide key; you could calculate an md5 or sha1 of the value and use that for the unique key instead (btw, you should use the binary representation of the hash).