Can somebody please show me how generate a sequence in MySQL 5.1?
create table users
(
user_id int unsigned not null auto_increment primary key,
username varbinary(32) unique not null
...
)
engine=innodb;
you could also do
drop table if exists users_seq;
create table users_seq
(
next_val int unsigned not null default 0
)
engine = innodb;
insert into users_seq values (0);
drop table if exists users;
create table users
(
user_id int unsigned not null primary key,
username varbinary(32) unique not null
)
engine=innodb;
delimiter #
create trigger users_before_ins_trig before insert on users
for each row
begin
declare v_id int unsigned default 0;
select next_val+1 into v_id from users_seq;
set new.user_id = v_id;
update users_seq set next_val = v_id;
end#
delimiter ;
insert into users (username) values ('f00'),('foo'),('bar');
select * from users;
select next_val from users_seq;
MySQL doesn't have sequences, however it does have the auto-increment feature.
http://www.experts123.com/q/does-mysql-5.1-have-sequences.html
CREATE TABLE test (
customer_id bigint(21) NOT NULL PRIMARY KEY AUTO_INCREMENT
);
Related
Dear MySQL pros out there: I wonder what I am doing wrong. My code is like:
use testdb;
drop table testtable;
create table testtable (
ID int NOT NULL,
lastn VARCHAR(20) NOT NULL,
firstn varchar(20));
Select * from testtable;
alter table testtable auto_increment = 7001;
insert into testtable (lastn,firstn) values('kim','jeff');
Select * from testtable;
insert into testtable (lastn,firstn) values('Lee','jim');
Select * from testtable;
The table generated as follows: (no effect from "alter" statement)
# ID, lastn, firstn
'0', 'kim', 'jeff'
'0', 'Lee', 'jim'
Either change your CREATE TABLE command to set the ID field to auto increment and initialise it like this:
create table testtable (
ID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
lastn VARCHAR(20) NOT NULL,
firstn varchar(20))
AUTO_INCREMENT = 7001;
or alter the table afterwards:
create table testtable (
ID int NOT NULL,
lastn VARCHAR(20) NOT NULL,
firstn varchar(20));
ALTER TABLE testtable MODIFY COLUMN ID INT PRIMARY KEY AUTO_INCREMENT;
ALTER TABLE testtable AUTO_INCREMENT = 7001;
ID needs to be both AUTO_INCREMENT and the PRIMARY KEY. (Those are "sufficient" but not completely "necessary".)
I'll like to find out if it's possible to do the following:
after insertion of data into table a, a row will be created automatically in table b and the Note_Id (its primary key) will be stored in one of the attributes (which is a foreign key that references to the primary key in table b) in table a.
CREATE TABLE table_a ( D_Id int(5) NOT NULL AUTO_INCREMENT,
User_Id int(8) not null,
Note_Id int(5) not null, -- this is the foreign key that points to table b
PRIMARY KEY (D_Id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE table_b ( Note_Id int(5) NOT NULL AUTO_INCREMENT,
Note_Description varchar(50) null,
PRIMARY KEY (Note_Id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Thanks!
delimiter $$
CREATE TRIGGER ins_Document
AFTER INSERT ON TABLE_A FOR EACH ROW
BEGIN
set #notenum=(Select max(Note_Id) from TABLE_B);
if(#notenum=0) then begin new.Note_Id=1;
end;
else
new.Note_Id=#notenum+1;
end if;
INSERT INTO TABLE_B (Note_Id) VALUES (NEW.Note_Id);
END$$
delimiter ;
Have a look into triggers: Create Trigger
Here you can react on events like inserts into a table and define respective actions for that.
I Want to add an Integer Column to a String that's because i need to generate a varchar variable with a numeric part that automatically increments. For example, P000001,P000002...
In order to do that what i am doing while creation of table i have taken an int field ID which auto_increments and i am Concatenating P with 00000 and the ID value
The Table i have created is :
CREATE TABLE tblAcceptTest(
ID int AUTO_INCREMENT NOT NULL primary key,
PatientID as CONCAT('P' , CONCAT('000000',CAST(ID as char)))
);
It Shows me the error from as keyword.
Please help
MySQL's documentation (http://dev.mysql.com/doc/refman/5.1/en/create-table.html) says, "the default value must be a constant; it cannot be a function or an expression." Why don't you just get the PatientID value afterward as part of the SELECT:
SELECT CONCAT('P', LPAD(ID, 6, 0)) AS PatientID FROM tblAcceptTest;
It looks like you want six digits after the "P", so try this for your expression:
CONCAT('P', LPAD(ID, 6, '0'))
Mysql has little support for computed columns.
Patient ID from your specification could be a char(7)
CREATE TABLE tblAcceptTest(
ID int AUTO_INCREMENT NOT NULL primary key,
PatientID char(7)
);
Then create some triggers. Note that the following insert trigger will cause issues with high concurrency servers.
DELIMITER |
CREATE TRIGGER tblAcceptTest_insert BEFORE INSERT ON tblAcceptTest
FOR EACH ROW BEGIN
DECLARE next_id INT;
SET next_id = (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='tblAcceptTest');
SET NEW.PatientID = CONCAT('P' , RIGHT(CONCAT('000000',next_id),6)) ;
END;
|
CREATE TRIGGER tblAcceptTest_update BEFORE UPDATE ON tblAcceptTest
FOR EACH ROW BEGIN
SET NEW.PatientID = CONCAT('P' , RIGHT(CONCAT('000000',NEW.ID),6)) ;
END;
|
DELIMITER ;
You use relationships and views to achieve the same result.
CREATE TABLE `patient` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`patient` varchar(60) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `accepted_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`patient_id` int(11) NOT NULL,
`accepted` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `patient_id` (`patient_id`),
CONSTRAINT `accepted_test_ibfk_1` FOREIGN KEY (`patient_id`) REFERENCES `patient` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create or replace view accepted_test_veiw as
select CONCAT('P' , RIGHT(CONCAT('000000',patient_id),6)) patient_key
, accepted
, id accepted_test_id
, patient_id
from accepted_test ;
select * from `accepted_test_veiw`
For a project we do the database design at the moment. We think we should use two auto_increment fields in one table.
table master:
`pid` int(10) NOT NULL auto_increment,
`iid` int(10) NOT NULL auto_increment,
...
To start with a alternate auto_incremet you can use ALTER TABLE tbl AUTO_INCREMENT = 100000; This will work only for the whole table 'tbl'.
auto_increment for pid should be 50000000 and auto_increment for iid should be 80000000
We want to avoid splitting it into 3 tables with relations master -> table.pid and master -> table.iid.
altering the table is not working cause
/* SQL Error (1075): Incorrect table definition; there can be only one auto column and it must be defined as a key */
Is it possible or what alternative do you recommend?
If you cannot use two auto columns I think you must redesign your database. What do you need exactly?
I dont fully understand your question but you can use triggers to maintain key values like the following:
drop table if exists grid;
create table grid
(
grid_id int unsigned not null auto_increment primary key,
name varchar(255) not null,
next_token_id int unsigned not null default 0,
next_node_id int unsigned not null default 0
)
engine = innodb;
drop table if exists grid_token;
create table grid_token
(
grid_id int unsigned not null,
token_id int unsigned not null,
name varchar(255) not null,
primary key (grid_id, token_id) -- note clustered PK order (innodb only)
)
engine = innodb;
drop table if exists grid_node;
create table grid_node
(
grid_id int unsigned not null,
node_id int unsigned not null,
name varchar(255) not null,
primary key (grid_id, node_id) -- note clustered PK order (innodb only)
)
engine = innodb;
-- TRIGGERS
delimiter #
create trigger grid_token_before_ins_trig before insert on grid_token
for each row
begin
declare tid int unsigned default 0;
select next_token_id + 1 into tid from grid where grid_id = new.grid_id;
set new.token_id = tid;
update grid set next_token_id = tid where grid_id = new.grid_id;
end#
create trigger grid_node_before_ins_trig before insert on grid_node
for each row
begin
declare nid int unsigned default 0;
select next_node_id + 1 into nid from grid where grid_id = new.grid_id;
set new.node_id = nid;
update grid set next_node_id = nid where grid_id = new.grid_id;
end#
delimiter ;
-- TEST DATA
insert into grid (name) values ('g1'),('g2'),('g3');
insert into grid_token (grid_id, name) values
(1,'g1 t1'),(1,'g1 t2'),(1,'g1 t3'),
(2,'g2 t1'),
(3,'g3 t1');
insert into grid_node (grid_id, name) values
(1,'g1 n1'),(1,'g1 n2'),
(2,'g2 n1'),
(3,'g3 n1'),(3,'g3 n2');
select * from grid;
select * from grid_token;
select * from grid_node;
I have a proposals table like this
- ID (auto_increment)
- proposal_id
- client_id
There a way in sql that the proposal_id increments just for each client_id
example:
ID proposal_id client_id
1 1 1
2 1 2
3 2 1
4 3 1
5 2 2
6 3 2
i know i can get the last poposal_id and +1 and i add the new entry... but i dont want to do a sql instruction just to get this value... instead i want to use in a sql!
Tkz
Roberto
As I understand you wish to have proposal_id as a sequence in a continuos manner per client_id. Either you should normalize the table to split into per-client-table [tricky and not advisable] to do this or write a SELECT
I think this is what you want if using innodb (recommended) although you can simplify this with myisam
delimiter ;
drop table if exists customer;
create table customer(
cust_id int unsigned not null auto_increment primary key,
name varchar(255) unique not null,
next_proposal_id smallint unsigned not null default 0
)engine = innodb;
insert into customer (name) values ('c1'),('c2'),('c3');
drop table if exists proposal;
create table proposal(
cust_id int unsigned not null,
proposal_id smallint unsigned not null,
proposal_date datetime not null,
primary key (cust_id, proposal_id) -- composite clustered primary key
)engine=innodb;
delimiter #
create trigger proposal_before_ins_trig before insert on proposal for each row
begin
declare new_proposal_id smallint unsigned default 0;
select next_proposal_id+1 into new_proposal_id from customer
where cust_id = new.cust_id;
update customer set next_proposal_id = new_proposal_id where cust_id = new.cust_id;
set new.proposal_id = new_proposal_id;
set new.proposal_date = now();
end#
delimiter ;
insert into proposal (cust_id) values (1),(2),(1),(3),(2),(1),(1),(2);
select * from proposal;
select * from customer;
hope it helps :)
i've added the myisam version below for good measure:
drop table if exists customer;
create table customer(
cust_id int unsigned not null auto_increment primary key,
name varchar(255) unique not null
)engine = myisam;
insert into customer (name) values ('c1'),('c2'),('c3');
drop table if exists proposal;
create table proposal(
cust_id int unsigned not null,
proposal_id smallint unsigned not null auto_increment,
proposal_date datetime not null,
primary key (cust_id, proposal_id) -- composite non clustered primary key
)engine=myisam;
insert into proposal (cust_id,proposal_date) values
(1,now()),(2,now()),(1,now()),(3,now()),(2,now()),(1,now()),(1,now()),(2,now());
select * from customer;
select * from proposal order by cust_id;
I think that you could design a complicated enough query to take care of this without any non-sql code, but that's not in the spirit of what you're asking. There is not a way to create the type of field-specific increment that you're asking for as a specification of the table itself.