SQL trigger to return unique code

Hi,

I have recently upgraded my MS Access program to SQL BE and i'm trying to get a SQL trigger setup.  When the tb_quotation01 table is updated i need to populate the the quotation_number with a unique number generated from the customer_code entered, a number between 001 and 999 with QU appended to to the start (eg. QU255001).

This quotation_number needs to then be returned to the original form and populated into the quotation_number filed so the user can see it.

I hope someone can assist me.

Regards,
Tom
d10u4vAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

rob_farleyCommented:
How does this grab you?

update t set quotation_number = 'QU' + right('000' + cast(t.customer_code as varchar(3)),3) + right('000' + cast((select count(*) + 1 from tb_quotation t2 where t2.customer_code = t.customer_code) as varchar(3)),3)
from
  tb_quotation01 t
  join
  inserted i
    on t.id = i.id
;


0
rob_farleyCommented:
Sorry, typo:

update t set quotation_number = 'QU' + right('000' + cast(t.customer_code as varchar(3)),3) + right('000' + cast((select count(*) + 1 from tb_quotation01 t2 where t2.customer_code = t.customer_code) as varchar(3)),3)
from
  tb_quotation01 t
  join
  inserted i
    on t.id = i.id
;
0
rob_farleyCommented:
And then to return it, you could have your trigger do something like:

select t.id, t.quotation_number
from
  tb_quotation01 t
  join
  inserted i
    on t.id = i.id
;

0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Chris LuttrellSenior Database ArchitectCommented:
Will that work on a multiple line insert or will that matter to you?  And triggers don't really return value to the calling program, that is up to stored procedures and such.
0
rob_farleyCommented:
update t set quotation_number = 'QU' + right('000' + cast(t.customer_code as varchar(3)),3) + right('000' + cast((select count(*) + i.rownum from tb_quotation01 t2 where t2.customer_code = t.customer_code) as varchar(3)),3)
from
  tb_quotation01 t
  join
  (select *, row_number() over (partition by customer_code order by id) as rownum from inserted) i
    on t.id = i.id
;

This will make sure that if you insert multiple records for the same customer_code, that they get separate quotation_numbers.

That what you mean, CGL?

Rob
0
Chris LuttrellSenior Database ArchitectCommented:
Yeah Rob, that was what I was refering to.   It is complicated to try to do something like this in a trigger, seems like a SP would be a better place.  The asker has not responded to see if any of this even matters to them.
Cheers,
Chris
0
Anthony PerkinsCommented:
>>The asker has not responded to see if any of this even matters to them.<<
Actually, I could be wrong, but despite Rob's best intentions I get the feeling it may have gone over their head.
0
Chris LuttrellSenior Database ArchitectCommented:
Trigger Logic can do that sometimes, :-)
0
rob_farleyCommented:
Actually, I'd prefer to give them a totally unique number using an identity field, so that the OUTPUT clause could do it.

So... suppose you had an id field... make a computed column like:

alter table tb_quotation01
add quotation_number as 'QU' + right('000' + cast(customer_code as varchar(3)),3) + right('000000000' + cast(id as varchar(10)),10) NOT NULL
;

So then you just use the OUTPUT clause on the insert:

INSERT tb_quotation01 (customer_code, otherdetails)
OUTPUT inserted.id, inserted.quotation_number
VALUES (55, 'Here are some other details');

But if you need the postfix to be generated on a per-customer basis, you can't use the 'newly generated id' concept so easily.

I forget - can a default value use a function that involves a query?

Rob
0
Anthony PerkinsCommented:
Perhaps a better (certainly more scalable) approach would be to store the next value in the customer table (or in a separate table), that way you grab it and increase by one and add all the other formatting characters.  Quite a few different ways to skin this cat.
0
Chris LuttrellSenior Database ArchitectCommented:
I like that answer Rob, I was thinking of a combination of computed column and Identity maybe for the incrementing number.
And nope, "Subqueries are not allowed in this context. Only scalar expressions are allowed."  You cannot use any kind of query in the default value.
0
rob_farleyCommented:
Yeah - and a scalar expression that uses a query can't act as a default either.
0
d10u4vAuthor Commented:
Hi

Thanks for the super response!  I had been looking at this all evening trying to figure it out and asked the question just before going to bed :) sorry for the delay in responding.

With regards to retiring the quotation number to the program; I only need this so that the user sees the quotation number which has been generated.  Would it be possible to generated the new quotation number using the trigger and then requery the form?

If not, how would the stored procedure method work.  As you can see, I'm a little new to the SQL side if things, but very willing to learn.

Thanks so much for all your help so far!
0
d10u4vAuthor Commented:
Can anyone advise on this topic?  I'm having a few issues.
0
rob_farleyCommented:
If you're using a stored procedure, then it makes life much easier.

Pass in your list of parameters, including @customer_code, and then have an insert statement that looks something like:

insert tb_quotation01 (col1, col2, ..., quotation_number)
output inserted.quotation_number
select @param1, @param2, ....., 'QU' + right('000' + cast(@customer_code as varchar(3)),3) + right('000' + cast((select count(*) + 1 from tb_quotation01 t2 where t2.customer_code = @customer_code) as varchar(3)),3)
;

Then your stored procedure will produce a resultset of your quotation_number field and you'll be able to pick this up easily in your application.

Rob
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Access

From novice to tech pro — start learning today.