I am creating a customer table with a parent table that is company.
It has been dictated(chagrin) that I shall create a primary key for the customer table that is a combination of the company id which is an existing varchar(4) column in the customer table, e.g. customer.company
The rest of the varchar(9) primary key shall be a zero padded counter incrementing through the number of customers within that company.
E.g. where company = MSFT and this is a first insert of an MSFT record: the PK shall be MSFT00001
on subsequent inserts the PK would be MSFT00001, MSFT00002 etc.
Then when company = INTL and its first record is inserted, the first record would be INTL00001
I began with an instead of trigger and a udf that I created from other stackoverflow responses.
ALTER FUNCTION [dbo].[GetNextID]
(
@in varchar(9)
)
RETURNS varchar(9) AS
BEGIN
DECLARE @prefix varchar(9);
DECLARE @res varchar(9);
DECLARE @pad varchar(9);
DECLARE @num int;
DECLARE @start int;
if LEN(@in)<9
begin
set @in = Left(@in + replicate('0',9) , 9)
end
SET @start = PATINDEX('%[0-9]%',@in);
SET @prefix = LEFT(@in, @start - 1 );
declare @tmp int;
set @tmp = len(@in)
declare @tmpvarchar varchar(9);
set @tmpvarchar = RIGHT( @in, LEN(@in) - @start + 1 )
SET @num = CAST( RIGHT( @in, LEN(@in) - @start + 1 ) AS int ) + 1
SET @pad = REPLICATE( '0', 9 - LEN(@prefix) - CEILING(LOG(@num)/LOG(10)) );
SET @res = @prefix + @pad + CAST( @num AS varchar);
RETURN @res
END
How would I write my instead of trigger to insert the values and increment this primary key. Or should I give it up and start a lawnmowing business?
Sorry for that tmpvarchar variable SQL server was giving me strange results without it.
Whilst I agree with the naysayers, the principle of “accepting that which cannot be changed” tends to lower the overall stress level, IMHO. Try the following approach.
Disadvantages
On the up side, though, this approach doesn’t have any race conditions associated with it, and it isn’t too egregious a hack to really and truly offend my sensibilities. So…
First, start with a key generation table. It will contain 1 row for each company, containing your company identifier and an integer counter that we’ll be bumping up each time an insert is performed.
Second, you’ll need a stored procedure like this (in fact, you might want to integrate this logic into the stored procedure responsible for inserting the customer record. More on that in a bit). This stored procedure accepts a company identifier (e.g. ‘MSFT’) as its sole argument. This stored procedure does the following:
SELECTstatement.Here you go:
The reason you might want to integrate this into the stored procedure that inserts a row into the customer table is that it makes globbing it all together into a single transaction; without that, your customer numbers may/will get gaps when an insert fails land gets rolled back.