I have an auto incremented field in my table. It should reset every new year 01/01 and then the prefix part should increment.
For example in 2016 my auto incremented field was A1,A2,A3..... etc but on 12:00 AM 2017 it should reset to B1 and go from there `(B1,B2,B3... etc), until Z when prefix should stop incrementing.
I created two tables... one for integer and one for varchar
CREATE TABLE t1
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE t2
(
id VARCHAR(1) NOT NULL PRIMARY KEY DEFAULT '0', name VARCHAR(30)
);
and am creating a trigger
DELIMITER $$
CREATE TRIGGER tg1
BEFORE INSERT ON t1
FOR EACH ROW
BEGIN
INSERT INTO t2 VALUES (NULL);
SET NEW.id = CONCAT('A', LPAD(LAST_INSERT_ID(), 3, '0'));
END$$
DELIMITER ;
but am not sure how to involve date.
My db is mysql
Related
Is there a way to set at the time of creating a table a custom ID with some character as prefix and the rest are numbers which is auto incremented so that the first time a record is inserted the ID will be "UID0000001" and the second time a record is inserted the ID will be "UID0000002" and so on automatically in MySQL.
You could do it in the database via a trigger. What you would need to do is to use an auto_increment-column and get the value of it in the BEFORE-trigger:
delimiter $$
drop table thetable
$$
create table thetable (
id int auto_increment,
id_text varchar(20),
another varchar(20),
primary key(id),
unique index(id_text)
)
$$
CREATE TRIGGER thetable_ibefore
BEFORE INSERT ON thetable
FOR EACH ROW
BEGIN
DECLARE v_id int;
select auto_increment into v_id
from information_schema.tables
where table_schema = database() and table_name = 'thetable';
SET NEW.id_text = concat('UID',substr(concat('000000', v_id), -7));
END;
$$
insert into thetable (another) values ('ABC')
$$
select * from thetable
$$
Assuming the prefix would always be UID, then you should just maintain an auto increment id column and then build the UIDxxxxx value when you query or in your presentation layer. If the prefix could vary, then you would need to state the rules if you want a concrete answer.
For example:
CREATE TABLE yourTable (
id int NOT NULL AUTO_INCREMENT,
some_col varchar(255) NOT NULL,
-- other columns here
PRIMARY KEY (id)
);
SELECT CONCAT('UID', LPAD(id, 7, '0')) AS uid
FROM yourTable;
DROP TABLE IF EXISTS Sales;
CREATE TABLE Sales (
id INT AUTO_INCREMENT,
product VARCHAR(100) NOT NULL,
quantity INT NOT NULL DEFAULT 0,
fiscalYear SMALLINT NOT NULL,
fiscalMonth TINYINT NOT NULL,
CHECK(fiscalMonth >= 1 AND fiscalMonth <= 12),
CHECK(fiscalYear BETWEEN 2000 and 2050),
CHECK (quantity >=0),
UNIQUE(product, fiscalYear, fiscalMonth),
PRIMARY KEY(id)
);
DROP TABLE IF EXISTS log;
CREATE TABLE log (
id INT AUTO_INCREMENT PRIMARY KEY,
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
text VARCHAR(100)
);
Triggers
CREATE DEFINER=`root`#`localhost` TRIGGER `sales_AFTER_UPDATE` AFTER UPDATE ON `sales`
FOR EACH ROW
BEGIN
INSERT INTO log VALUES(NOW(),CONCAT('Update Student Record ', OLD.quantity));
END
UPDATE test for.sales SET quantity = 36
WHERE (id = 1);
ERROR 1136: 1136: Column count doesn't match value count at row 1
Iam new in mySQL Please help
You should specify columns in INSERT statement in your trigger explicitly, as you do not set all values in a row (auto incremented column excluded).
So it would be
INSERT INTO log(timestamp, text) VALUES (NOW(),CONCAT('Update Student Record ', OLD.quantity));
You have some errors.
First based on your trigger you need another column on log table which is as following
quantity INT NOT NULL DEFAULT 0
Second , do not use Keywords and Reserved Words like text and timestamp, it is a bad practice. If you do please put it inside backticks
Third your insert statement should be
INSERT INTO log(`timestamp`,`text`,quantity) VALUES(NOW(),'Update Student Record', OLD.quantity);
there is no need for CONCAT.
Fourth,
`sales`
table is not the same as Sales table, because you have used backticks.
Full working trigger below:
DELIMITER //
CREATE TRIGGER `sales_AFTER_UPDATE` AFTER UPDATE ON Sales
FOR EACH ROW
BEGIN
INSERT INTO log(`timestamp`,`text`,quantity) VALUES(NOW(),'Update Student Record', OLD.quantity);
END//
DELIMITER ;
Check working demo:
https://www.db-fiddle.com/f/iqwShcHK3AGJvU4MDbxDku/0
I am trying to use a trigger to insert the updated value to another table. I have two tables (table1 and table2).
I want to copy the new primary key of table1 to a non-primary key field in table2 in hexadecimal value. the primary key is integer type and the other field is varchar.
The code is as follows:
delimiter /
drop trigger if exists a /
create trigger a before insert on table1 for each row
begin
insert into table2 set table1ID= hex(new.id);
end /
insert into table1 set name='Ronnie';
But, the problem is when i insert into table1, the primary key will not be added to table2. it will add 0 instead.
These are the tables:
create table table1 (
id integer not null auto_increment primary key,
name varchar(45) not null
);
create table table2 (
id integer not null auto_increment primary key,
table1ID varchar(45) not null
);
Your trigger is "before insert", and the new generated id is not available yet. Change it to "after insert":
create trigger a after insert on table1 for each row
begin
insert into table2 (warehouseID) values (hex(new.id));
end /
Please see it here.
The given query is in mysql format. I want same query in SQL Server 2008.
CREATE TABLE table1_seq
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE table1
(
id VARCHAR(7) NOT NULL PRIMARY KEY DEFAULT '0', name VARCHAR(30)
);
Now the trigger
DELIMITER $$
CREATE TRIGGER tg_table1_insert
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
INSERT INTO table1_seq VALUES (NULL);
SET NEW.id = CONCAT('LHPL', LPAD(LAST_INSERT_ID(), 3, '0'));
END$$
DELIMITER ;
Then you just insert rows to table1
INSERT INTO Table1 (name)
VALUES ('Jhon'), ('Mark');
And you'll have
| ID | NAME |
------------------
| LHPL001 | Jhon |
| LHPL002 | Mark |
This may answer your question
-- create table with 'ABCD' as prefix, combining with identity column Id
CREATE TABLE dbo.Persons
(
Id int IDENTITY (1,1) NOT NULL
,PersonId AS ('ABCD' + CONVERT(varchar(20), Id)) PERSISTED NOT NULL PRIMARY KEY
,Name varchar(100)
);
GO
-- Do not specify calculated column when insert values into the table
INSERT INTO dbo.Persons (Name)
VALUES ('Person1'), ('Person2'), ('Person3');
GO
-- Display the records from the table
SELECT PersonId, Name
FROM dbo.Persons;
GO
This approach does not require to create a separate table and trigger, therefore efficient.
Hope this helps.
I'm trying to keep a list of current content and archived content in my PHP Internet application. I want to be able to identify the content that as archived as having an enddate, and the content that is not archived as having no enddate. It would be ideal if I could create more paths, but I'm hoping to just start here.
The first thing I'm noticing is that I'm getting a syntax error at the " on line 1, but there is no double quote where I create the table. The second issue I'm having is the use of TIMESTAMP as a datatype. I tried to use CURRENT_TIMESTAMP for the startdate, and it returned syntax errors. The final problem I am having is with the trigger construction. I'm not able to get down far enough to troubleshoot it. As soon as I get past the references, I'll also try to troubleshoot that.
CREATE TABLE plan(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(32),
startdate TIMESTAMP NOT NULL,
enddate TIMESTAMP);
CREATE TABLE level(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(32),
description VARCHAR(500),
startdate TIMESTAMP NOT NULL,
enddate TIMESTAMP);
CREATE TABLE planIDxlevelID(
planID INT NOT NULL REFERENCES plan(id),
levelID INT NOT NULL REFERENCES level(id),
arXORcur ENUM('archive', 'current');
);
delimiter |
CREATE TRIGGER testref BEFORE INSERT ON plan
FOR EACH ROW BEGIN
INSERT INTO plan(id, plan, startdate, enddate)
SET id = LAST_INSERT_ID( id + 1), name = NEW.name, startdate = NEW.UTC_TIMESTAMP, enddate = NULL;
UPDATE plan(enddate) WHERE plan.id = OLD.id
SET enddate = UTC_TIMESTAMP;
INSERT INTO planIDxlevelID(planID, levelID, arXORcur)
SET planID = NEW.planID, levelID = OLD.levelID, arXORcur = current;
UPDATE planIDxlevelID(planID, levelID, arXORcur) WHERE planID = OLD.planID
SET planID = OLD.planID, levelID = OLD.levelID, arXORcur = archive;
END;
|
delimiter ;
INSERT INTO plan (name) VALUES
"Frogs", "Toys", "Trucks", "Nature", "Seasons",
"Construction", "Candy", "Rainbows", "Telephone", "Breakfasts";
TIMESTAMP vs DATETIME
This is a classic gotcha: TIMESTAMP is a special datatype that
is updated with "now" every time the row is touched, whether you update it to another value or leave it alone. What you want is DATETIME.
Next, you have numerous syntax and other errors. The following executes without error, however it may not now have the logic you want, but you can edit it to fix that:
CREATE TABLE plan (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(32),
startdate DATETIME NOT NULL, -- changed TIMESTAMP to DATETIME
enddate DATETIME -- changed TIMESTAMP to DATETIME
);
CREATE TABLE level (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(32),
description VARCHAR(500),
startdate DATETIME NOT NULL, -- changed TIMESTAMP to DATETIME
enddate DATETIME -- changed TIMESTAMP to DATETIME
);
CREATE TABLE planIDxlevelID (
planID INT NOT NULL REFERENCES plan(id),
levelID INT NOT NULL REFERENCES level(id),
arXORcur ENUM('archive', 'current')
);
DROP TRIGGER IF EXISTS test_insert;
delimiter |
CREATE TRIGGER test_insert BEFORE INSERT ON plan
FOR EACH ROW BEGIN
INSERT INTO plan (id, plan, startdate)
values (LAST_INSERT_ID() + 1, NEW.name, NEW.UTC_TIMESTAMP());
INSERT INTO planIDxlevelID (planID, levelID, arXORcur)
values (NEW.ID, null, arXORcur = current);
END;|
delimiter ;
DROP TRIGGER IF EXISTS test_update;
delimiter |
CREATE TRIGGER test_update BEFORE UPDATE ON plan
FOR EACH ROW BEGIN
UPDATE plan SET
enddate = UTC_TIMESTAMP
WHERE plan.id = OLD.id;
UPDATE planIDxlevelID SET
planID = NEW.ID,
levelID = null,
arXORcur = archive
WHERE planID = OLD.ID;
END;|
delimiter ;
INSERT INTO plan (name) VALUES
("Frogs"), ("Toys"), ("Trucks"), ("Nature"), ("Seasons"),
("Construction"), ("Candy"), ("Rainbows"), ("Telephone"), ("Breakfasts");