MySQL INSERT BEFORE TRIGGER Fails? - mysql

I'm running MySQL 5.1.48 on Windows XP and the following trigger test doesn't work:
-- Drop the old table
DROP TABLE IF EXISTS `ikasan01`.`ikasanwiretap`;
-- Create
CREATE TABLE `ikasan01`.`ikasanwiretap` (
`Id` bigint(20) NOT NULL AUTO_INCREMENT,
`ModuleName` varchar(255) NOT NULL,
`FlowName` varchar(255) NOT NULL,
`ComponentName` varchar(255) NOT NULL,
`EventId` varchar(255) NOT NULL,
`PayloadId` varchar(255) NOT NULL,
`PayloadContent` varchar(255) NOT NULL,
`CreatedDateTime` datetime NOT NULL,
`UpdatedDateTime` datetime NOT NULL,
`Expiry` datetime NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- In order to use now() as a DEFAULT value on a datetime column we
have to do it via a BEFORE INSERT TRIGGER
CREATE TRIGGER defaultUpdateDateTime
BEFORE INSERT ON ikasanwiretap FOR EACH ROW
SET NEW.UpdatedDateTime = now();
-- Test the trigger
insert into IkasanWiretap (ModuleName, FlowName, ComponentName,
EventId, PayloadId, PayloadContent, CreatedDateTime, Expiry) values
('3', '3', '3', '3', '3', '3', now(), now());
On my trigger test I still get the MySQL server stating that the UpdateDateTime has no default value.
I've tried just about everything at my disposal so I thought I'd ask you helpful lot ;) Any ideas?
Cheers,
Martijn
PS: X-posted on the London Java User Group and the Ikasan EIP Mailing list.

I guess the trigger is started after the "not null" constraints are verified.
Remove the "not null" on UpdatedDateTime.

Related

Mysql autoincrement error when insert a new register

I have this table
CREATE TABLE IF NOT EXISTS `test`.`Challenge` (
`idChallenge` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NOT NULL,
`description` VARCHAR(45) NULL DEFAULT NULL,
`start` DATETIME NOT NULL,
`ending` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`idChallenge`),
UNIQUE INDEX `name_UNIQUE` (`name` ASC))
ENGINE = InnoDB;
When I try insert a new register:
insert into challenge (name, start) values ("test", now());
Gives me this error:
Error Code: 1364. Field 'id_challenge' doesn't have a default value
But first I don't have this column in my table and if I put it is create.
Us must use backticks ` for reserved words.
insert into Challenge (`name`, `start`) values ("test", now());
The problem are with idChallenge, if I change it to idchallenge works.

how to write create table date query in phpmyadmin which store by default current date if date not given?

I am trying to create a table (phpMyAdmin) by using the following query:
CREATE TABLE login_detail(
Id int(11) primary key auto_increment,
userName varchar(100) not null,
userPassword varchar(100) not null,
created_at Date DEFAULT CURRENT_DATE
);
but it showing error at CURRENT_DATE. Can anyone solve this problem?
Its not supported.
The DEFAULT clause specifies a default value for a column. With one exception, the default value must be a constant; it cannot be a function or an expression. This means, for example, that you cannot set the default for a date column to be the value of a function such as NOW() or CURRENT_DATE. The exception is that you can specify CURRENT_TIMESTAMP as the default for a TIMESTAMP column
http://dev.mysql.com/doc/refman/5.5/en/create-table.html
you just use current time stamp .below code i tested in phpmyadmin.it working fine
CREATE TABLE login_detail(Id int(11) primary key auto_increment, userName varchar(100) not null,userPassword varchar(100) not null, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Try the following:
CREATE TABLE IF NOT EXISTS `login_detail` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(100) NOT NULL,
`userPassword` varchar(100) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`Id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
INSERT INTO `login_detail` (`Id`, `userName`, `userPassword`) VALUES
(1, 'aaa', 'bbb'),
(2, 'aaa', 'bbb');
To get the date and-or time in the format you want use DATE_FORMAT
SELECT `Id`, `userName`, `userPassword`, DATE_FORMAT(`created_at`, '%e %b %Y') AS `created_at_date`, DATE_FORMAT(`created_at`, '%H:%i:%s') AS `created_at_time` FROM `login_detail`;
http://sqlfiddle.com/#!9/ea673/1

mySQL trigger? causing Error Code: 1048 Column cannot be null

I have seen similar questions asked but never seen an answer that works for me. I have the following table and trigger definitions...
DROP TRIGGER IF EXISTS c_consumption.newRateHistory;
DROP TABLE IF EXISTS c_consumption.myrate;
DROP TABLE IF EXISTS c_consumption.myratehistory;
USE c_consumption;
CREATE TABLE `myrate` (
`consumerId` varchar(255) DEFAULT NULL,
`durationType` varchar(50) NOT NULL DEFAULT 'DAY',
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`itemId` varchar(50) NOT NULL,
`quantity` double NOT NULL DEFAULT 1.0,
`quantityType` varchar(100) NOT NULL DEFAULT 'GALLON',
`timePeriod` double NOT NULL DEFAULT 1.0,
PRIMARY KEY (`id`),
UNIQUE INDEX `UNIQUE_RATE`
(`itemId` ASC, `consumerId` ASC)
) ENGINE=InnoDB AUTO_INCREMENT=314 DEFAULT CHARSET=utf8;
CREATE TABLE `myratehistory` (
`consumerId` varchar(255) DEFAULT NULL,
`durationType` varchar(50) DEFAULT NULL,
`itemId` varchar(50) NOT NULL,
`quantity` double DEFAULT NULL,
`quantityType` varchar(100) DEFAULT NULL,
`status` varchar(20) NOT NULL DEFAULT 'CREATED',
`timePeriod` double DEFAULT NULL,
`timestamp` DATETIME NULL,
PRIMARY KEY (`itemId`, `consumerId`, `timestamp`)
) ENGINE=InnoDB AUTO_INCREMENT=314 DEFAULT CHARSET=utf8;
CREATE TRIGGER `newRateToHistory`
AFTER INSERT
ON myrate
FOR EACH ROW
INSERT INTO myratehistory
(
consumerId,
durationType,
itemId,
quantity,
quantityType,
status,
timePeriod,
timestamp
)
VALUES(
new.consumerId,
new.durationType,
new.itemId,
new.quantity,
new.quantityType,
'CREATED',
new.timePeriod,
now());
Note that consumerId CAN be null.
Next I run this SQL statement:
INSERT INTO c_consumption.myrate (
consumerId,
durationType,
itemId,
quantity,
quantityType,
timePeriod)
VALUES(
null,
'DAY',
'MyItem',
1.0,
'GALLON',
1.0);
I get the following message:
Error Code: 1048 Column 'consumerId' cannot be null
Obviously I am doing something wrong but I do not know what it is. Any help would be greatly appreciated.
Thanks!
ConsumerId is part of the primary key. No part of the primary key can be null.
Just a guess, why mysql allows a null-able column as part of the primary key I don't know
CREATE TABLE `myratehistory` (
[...]
PRIMARY KEY (`itemId`, `consumerId`, `timestamp`)
Your MySQL server is running in "strict" mode, which throws an error in case like yours are otherwise handled "gracefully" without strict mode.
As of MySQL 5.7.5, the default SQL mode includes STRICT_TRANS_TABLES, which is exactly the cause of your headache.
To change your server's mode, edit your my.cnf (or my.ini if you're running Windows) and set the mode to:
sql-mode=""
Then you must restart your mysql server like this:
service mysql reload
Or directly throw init.d process:
/etc/init.d/mysql reload
Hope it will help you.

Using Auto-Increment value in MYSQL Before Insert Trigger?

The users table:
CREATE TABLE `users` (
`id` int(8) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(45) DEFAULT NULL,
`username` varchar(16) DEFAULT NULL,
`salt` varchar(16) DEFAULT NULL,
`password` varchar(128) DEFAULT NULL,
`lastlogin` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`joined` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`loggedin` tinyint(1) unsigned NOT NULL DEFAULT '0',
`sessionkey` varchar(60) DEFAULT NULL,
`verifycode` varchar(16) DEFAULT NULL,
`verified` tinyint(1) unsigned NOT NULL DEFAULT '0',
`banned` tinyint(1) unsigned NOT NULL DEFAULT '0',
`locked` tinyint(1) unsigned NOT NULL DEFAULT '0',
`ip_address` varchar(45) DEFAULT NULL,
`failedattempts` tinyint(1) unsigned NOT NULL DEFAULT '0',
`unlocktime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
The user_records table:
CREATE TABLE `user_records` (
`id` int(8) unsigned NOT NULL AUTO_INCREMENT,
`userid` int(8) unsigned DEFAULT NULL,
`action` varchar(100) DEFAULT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
The before insert trigger on the users table:
USE `gknet`;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` TRIGGER `before_create_user` BEFORE INSERT ON `users` FOR EACH ROW BEGIN
INSERT INTO user_records (action, userid, timestamp)
VALUES ('CREATED', ID, NOW() );
END
Basically, my problem here is that on the trigger when I try to put in the id of the user that's automatically assigned by MySQL (PK, NN, Auto-Increment), it just puts in 0 for userid on the user_records table. How would I do it so it would select the id that the user is being assigned by SQL, and put it in as userid on the records entry (where the ID is right after 'CREATED')?
Also, if you see any other optimizations that could be made on the tables, feel free to let me know :D
OP's comment:
How would I do it before, thou?
You can find current auto_increment value that is to be assigned to a new record.
And use the same in the before trigger as a parent user id for user_records table.
You have to query information_schema.tables table to find the value.
Example:
use `gknet`;
delimiter $$
drop trigger if exists before_create_user; $$
create definer=`root`#`localhost` trigger `before_create_user`
before insert on `users`
for each row begin
declare fk_parent_user_id int default 0;
select auto_increment into fk_parent_user_id
from information_schema.tables
where table_name = 'users'
and table_schema = database();
insert into user_records ( action, userid, timestamp )
values ( 'created', fk_parent_user_id, now() );
end;
$$
delimiter ;
Observations:
As per mysql documentation on last_insert_id(),
"if you insert multiple rows using a single INSERT statement,
LAST_INSERT_ID() returns the value generated for the first inserted
row only."
hence, depending on last_insert_id() and auto_increment field values in batch inserts seems not reliable.
Change the trigger to after insert instead of before insert and use NEW to get the last inserted id
USE `gknet`;
DELIMITER $$
CREATE DEFINER=`root`#`localhost`
TRIGGER `after_create_user` AFTER INSERT ON `users`
FOR EACH ROW
BEGIN
INSERT INTO user_records (action, userid, timestamp)
VALUES ('CREATED', NEW.ID, NOW() );
END; $$
PLEASE USE AFTER INSERT AND UPDATE
Do not make auto_increment any column you want to manipulate explicitly. That can confuse an engine and cause serious problems. If no column you have used for primary key are auto_increment you can do anything you want with them via triggers. Sure generated values will be rejected if they violate the mandatory uniqness of the primary key.
maybe this solution can
BEGIN
DECLARE id int;
SELECT MAX(table_id)
FROM table
INTO id;
IF id IS NULL THEN
SET NEW.column=(CONCAT('KTG',1));
ELSE
SET NEW.column=(CONCAT('KTG',id+1));
END IF;
END

MySQL - Cannot insert NULL value in column, but I have a default value specified?

I have a table in MySQL that have a few columns that have default values specified, but when I try to insert a row, (not specifying values for those default columns), it throws an error saying I cannot insert NULL values.
Here is the table example;
CREATE TABLE `users` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`UniqueName` varchar(120) NOT NULL,
`Password` varchar(1000) NOT NULL,
`PublicFlag` tinyint(1) NOT NULL,
`NoTimesLoggedIn` int(10) unsigned NOT NULL DEFAULT '0',
`DateTimeLastLogin` timestamp NOT NULL DEFAULT '1971-01-01 00:00:00',
`UserStatusTypeId` int(10) unsigned NOT NULL,
`Private` tinyint(1) NOT NULL DEFAULT '0',
`SiteName` varchar(255) NOT NULL,
`CountryId` int(10) NOT NULL DEFAULT '0',
`TimeZoneId` varchar(255) NOT NULL DEFAULT 'UTC',
`CultureInfoId` int(10) unsigned NOT NULL DEFAULT '0',
`DateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UserCreated` int(10) unsigned NOT NULL,
`LastUpdatedBy` int(10) unsigned NOT NULL,
`DateLastUpdated` datetime DEFAULT NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `UniqueName_UNIQUE` (`UniqueName`),
KEY `Index 3` (`SiteName`)
)
It complains about TimeZoneId, and when I populate TimeZoneId, it complains about CultureInforId.
I am using MySQL Version: 5.1.43-community
Here is the insert query I am trying to insert, grabbed from NHibernate Profiler:
INSERT INTO Users
(UniqueName,
Password,
PublicFlag,
NoTimesLoggedIn,
DateTimeLastLogin,
SiteName,
TimeZoneId,
DateCreated,
DateLastUpdated,
Private,
CountryId,
CultureInfoId,
UserCreated,
LastUpdatedBy,
UserStatusTypeId)
VALUES ('zma#zm.com','u1uhbQviLp89P9b3EnuN/Prvo3A4KVSiUa0=',1,
0,'1/01/1971 12:00:00 AM','V9O1T80Q6D',NULL,'2/08/2010 2:13:44 AM',
'2/08/2010 2:13:44 AM',0, NULL, NULL, 4, 4,31)
Use the DEFAULT keyword instead:
INSERT INTO users (TimeZoneId) VALUES (DEFAULT);
Do not insert NULL values. I'm assuming you were trying this syntax:
INSERT INTO users VALUES (null, 'Jones', 'yarg', 1, null, null, null);
Instead, use this syntax:
INSERT INTO users SET UniqueName='Jones', Password='yarg';
For more info, see the MySQL docs on INSERT.
You have "NOT NULL" set on fields that you are trying to INSERT NULL on.
eg.
CountryId,
CultureInfoId,
TimeZoneId
execute the following:
ALTER TABLE `users` MODIFY `CountryId` int(10) DEFAULT '0' NULL;
ALTER TABLE `users` MODIFY `CultureInfoId` int(10) unsigned DEFAULT '0' NULL;
ALTER TABLE `users` MODIFY `TimeZoneId` varchar(255) DEFAULT 'UTC' NULL;
EDIT: Didn't realize he wanted the default value instead of NULL on "null" insert. Basically as already has been suggested use the DEFAULT keyword in place of NULL on the values.
OR leave the NULL fields and values out altogether and mysql will use the defined defaults eg.
INSERT INTO Users
(UniqueName,
Password,
PublicFlag,
NoTimesLoggedIn,
DateTimeLastLogin,
SiteName,
DateCreated,
DateLastUpdated,
Private,
UserCreated,
LastUpdatedBy,
UserStatusTypeId)
VALUES ('zma#zm.com','u1uhbQviLp89P9b3EnuN/Prvo3A4KVSiUa0=',1,
0,'1/01/1971 12:00:00 AM','V9O1T80Q6D','2/08/2010 2:13:44 AM',
'2/08/2010 2:13:44 AM',0, 4, 4,31)
The documentation says that from version 5.6 you need to access fields by default.
I've read this post about this trouble
I've fixed it this way:
mysql> show global variables like 'explicit_defaults_for_timestamp';
And if your field has ON value change to OFF
mysql> set global explicit_defaults_for_timestamp=0;
That's all.
As an alternative to using the DEFAULT keyword you can also just not specify values for the fields which you want to have default values. For instance if you just removed TimeZoneId, CountryId and CultureInfoId from your query entirely those columns will receive the default values automatically:
INSERT INTO Users
(UniqueName,
Password,
PublicFlag,
NoTimesLoggedIn,
DateTimeLastLogin,
SiteName,
DateCreated,
DateLastUpdated,
Private,
UserCreated,
LastUpdatedBy,
UserStatusTypeId)
VALUES
('zma#zm.com','u1uhbQviLp89P9b3EnuN/Prvo3A4KVSiUa0=',1,0,
'1/01/1971 12:00:00 AM','V9O1T80Q6D','2/08/2010 2:13:44 AM',
'2/08/2010 2:13:44 AM',0,4,4,31)
I'm not sure how that would work in the context of NHibernate however as that part of the question wasn't quite as well explained.
TimeZoneIdvarchar(255) NOT NULL DEFAULT 'UTC',
CultureInfoId` int(10) unsigned NOT NULL DEFAULT '0',
For this fields you have set constraints as "Not Null" and hence values inserted can't be null and hence either alter the table structure or just not specify values for the fields which you want to have default values.