Reputation: 47
Is there a way we can increment a column declared as varchar in PostgreSQL. IF I have values 0001,0002,0003... in my column how can proceed to add +1? I tried nextval but it not working.
CREATE TABLE tab1 (
matri VARCHAR(10) NOT NULL,
role VARCHAR(4) NOT NULL,
libelle VARCHAR(40),
util VARCHAR(10),
)
CREATE TABLE tab2 (
idemploye SERIAL,
nomred VARCHAR(10),
matri VARCHAR(10),
)
Insert into tab1 ("matri", "role", "libelle", "util")
select tab2.matri,tab1.role,'MANAGER',E'MANAGER' from tab1,tab2
where tab2.matri IN (Select matri from tab2);
I want my second column "role" to be incremented with every insert.
Upvotes: 1
Views: 3031
Reputation: 639
Though the better solution would be to use an integer column and add the padding on display, this works:
CREATE SEQUENCE role_seq;
CREATE TABLE roles (role varchar(4) NOT NULL DEFAULT lpad(nextval('role_seq')::varchar, 4, '0'));
INSERT INTO roles VALUES (DEFAULT), (DEFAULT);
SELECT * FROM roles;
-- role
-- ------
-- 0001
-- 0002
Note that you will get gaps in the numbers if you delete rows or an insert transaction rolls back.
Upvotes: 2
Reputation: 3102
As a_horse_with_no_name has already stated, the ideal here is to store this as an int and format on display, but I assume your system is the way it is for a reason, so.
The way to do this would be, in the select subquery of your insert statement: select the highest existing value, cast to int, increment, cast back to varchar, run through lpad
, and then just in case no data exists yet, coalesce with '0001'.
insert into tab1 ("matri", "role", "libelle", "util")
select
tab2.matri,
coalesce((select lpad((role::integer + 1)::varchar, 4, '0') from tab1 order by role desc limit 1), '0001'),
'MANAGER',
E'MANAGER'
from
tab2
where
tab2.matri IN (select matri from tab2);
An alternative approach would be to create a trigger to do this for you, so you don't need to do this manually everywhere you insert into the table:
-- Create trigger function
create or replace function tg_fn_tab1_varchar_increment(
) returns trigger as $$
declare
_r varchar;
begin
select into _r
role
from
tab1
order by
role desc
limit 1;
if _r is null then
NEW.role := '0001';
return NEW;
end if;
NEW.role := lpad((_r::integer + 1)::varchar, 4, '0');
return NEW;
end;
$$ language plpgsql volatile;
-- Attach trigger
create trigger tg_tab1_varchar_increment before insert on tab1
for each row execute procedure tg_fn_tab1_varchar_increment();
Upvotes: 0
Reputation: 51
Try this...
select CONVERT(varchar,substring('0001',1,2)) +
RIGHT(REPLICATE('0',5) + convert(varchar,(CONVERT(int, substring('0001',3,5)) + 1)) ,5);
Upvotes: -1