sql server (alternate):
I have a feeling I'll be forced to use a script and a trigger for this type of field format but I'm wondering if any of your wizards could point at a simple way I could do something like this: For example, if I want to be able to keep track of new orders following this incrementing convention: ORD100000001 ORD100000002 ORD100000003 .... etc ... Does MSSQL2000 have features that I can simply set for this kind of field or will I be resorting to writing up a SQL script and a trigger?
This table will also have other rows such as INV90000001 INV90000002 INV90000003 PYMT4000001 PYMT4000002 etc... For example, the next PYMT row would be PYMT4000003 so if I insert a row that is of type "Payment", it would autoincrement to this next value in the sequence. Since I would much prefer to keep tracking this kind of sequence, I would not be able to use the id column in this case. Jared
Jared Evans (jnevans@gmail.com) writes: [quoted text, click to view] > I have a feeling I'll be forced to use a script and a trigger for this > type of field format but I'm wondering if any of your wizards could > point at a simple way I could do something like this: > > For example, if I want to be able to keep track of new orders following > this incrementing convention: > > ORD100000001 > ORD100000002 > ORD100000003 > ... etc ... > > Does MSSQL2000 have features that I can simply set for this kind of > field or will I be resorting to writing up a SQL script and a trigger?
You could define this textual order ID as computed column: textid = 'ORD1' + space(8 - len(ltrim(str(id))) + ltrim(str(id)) id is here you numeric id column. This could be an IDENTITY column, or one that you increment yourself. Notice that if you have a requirement for ids being contiguous, you cannot use IDENTITY. This examples presumes that ORD1 is a fixed string. If ORD1 is variable, you might still be able to use a computed column if you compute ORD1 with a UDF. However, for the sake of performance, a trigger would be a lot better in this case. -- Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se Books Online for SQL Server SP3 at
I will be pursing this solution: I'll keep separate tables for ORD, INV, PYMT, etc. in each of these tables (the ORD table for example) Type, ID, TrxNum (the composite of previous 2 fields), etc ORD, 10000001, ORD1000001, etc ID would be an identity that increments by one. Insert a row into this table first, grab the identity and create and update(or calculated field) the TrxNum field. Take the TrxNum field to insert into other tables and use as link between the tables as the relationship.
Jared Evans (jnevans@gmail.com) writes: [quoted text, click to view] > This table will also have other rows such as > > INV90000001 > INV90000002 > INV90000003 > PYMT4000001 > PYMT4000002 > > etc... > > For example, the next PYMT row would be > PYMT4000003 > > so if I insert a row that is of type "Payment", it would autoincrement > to this next value in the sequence. > > Since I would much prefer to keep tracking this kind of sequence, I > would not be able to use the id column in this case.
You could have two columns, one with the type and one with the id. Or maybe even three, as that digit after the code is something you have not explained yet. And then you could have an computed column that composes the strings. If you will use the string for lookups, you will need to index the column. The one thing to keep in mind is to make sure that you will have a couple of settings on, as described in Books Online. Of these, the trickeist is ARITHABORT, since it is not ON by default. As for the id, you would have roll your own, but that's simple: BEGIN TRANSACTION SELECT @id = coalesce(MAX(id), 0) + 1 FROM tbl (UPDLOCK) WHERE type = @type INSERT tbl (id, type, ... VALUES (@id, @type, ... ... COMMIT TRANSACTION -- Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se Books Online for SQL Server SP3 at
I agree, I posted a similar response to the original post B4 I read this reponse. [quoted text, click to view] "Erland Sommarskog" <esquel@sommarskog.se> wrote in message news:Xns961260ED91B7BYazorman@127.0.0.1... > Jared Evans (jnevans@gmail.com) writes: > > This table will also have other rows such as > > > > INV90000001 > > INV90000002 > > INV90000003 > > PYMT4000001 > > PYMT4000002 > > > > etc... > > > > For example, the next PYMT row would be > > PYMT4000003 > > > > so if I insert a row that is of type "Payment", it would autoincrement > > to this next value in the sequence. > > > > Since I would much prefer to keep tracking this kind of sequence, I > > would not be able to use the id column in this case. > > You could have two columns, one with the type and one with the id. Or > maybe even three, as that digit after the code is something you have > not explained yet. And then you could have an computed column that composes > the strings. If you will use the string for lookups, you will need to > index the column. The one thing to keep in mind is to make sure that > you will have a couple of settings on, as described in Books Online. > Of these, the trickeist is ARITHABORT, since it is not ON by default. > > As for the id, you would have roll your own, but that's simple: > > BEGIN TRANSACTION > SELECT @id = coalesce(MAX(id), 0) + 1 FROM tbl (UPDLOCK) > WHERE type = @type > > INSERT tbl (id, type, ... > VALUES (@id, @type, ... > > ... > COMMIT TRANSACTION > > > -- > Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se > > Books Online for SQL Server SP3 at > http://www.microsoft.com/sql/techinfo/productdoc/2000/books.asp
[quoted text, click to view] >From further email discussions with Erland, using IDENTITY will not
reliably increment the field by one. I don't think I read that line close enough: "Notice that if you have a requirement for ids being contiguous, you cannot use IDENTITY. " I apologize for keeping pushing the IDENTITY issue to keep track of the sequence when you made it clear that it would not work the way I thought it would. I think I will be able to drop the project requirement for a contiguous sequence and defer to using the id field even if it may not always be incremented by one. That would reduce the load on the database and help it to scale better. I'm not sure if the benefit of using the next number in sequence would outweigh the performance penalty that would be incurred.
[posted and mailed, please reply in news] Jared Evans (jnevans@gmail.com) writes: [quoted text, click to view] > I will be pursing this solution: > > I'll keep separate tables for ORD, INV, PYMT, etc. > > in each of these tables (the ORD table for example) > > Type, ID, TrxNum (the composite of previous 2 fields), etc > ORD, 10000001, ORD1000001, etc > > ID would be an identity that increments by one. > Insert a row into this table first, grab the identity and create and > update(or calculated field) the TrxNum field. Take the TrxNum field > to insert into other tables and use as link between the tables as the > relationship.
I ask you again: can you accept sequences like: ORD1000001 ORD1000002 ORD1000004 ORD1000008 That is, can you accept gaps? If you cannot, do *not* use IDENTITY. Whether you should have separate tables at all, I can't tell, because I don't know the business and data model behind it. But if ORD100001 and PYMT400001 ends up the same table, you should not have separate tables. Particularly, if a new code could be added tomorrow, it's a very poor choice to have separate tables. If you have all in one table, is a matter of adding that new code to the table. If you have one table each, you will need to recode each time. Having separate tables only get access to the IDENTITY function is poor design, in my opinion. -- Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se Books Online for SQL Server SP3 at
What would you recommend as a solution to keep the sequence contiguous? Could you give an example of a such T-SQL function? I probably would start a transaction to take the value "ORD10000001" then do a left trim to remove the "ORD" from the value then increment it by one to make a value of "ORD10000002". Insert the new row and commit the transaction.
Jared Evans (jnevans@gmail.com) writes: [quoted text, click to view] > I think I will be able to drop the project requirement for a contiguous > sequence and defer to using the id field even if it may not always be > incremented by one. That would reduce the load on the database and > help it to scale better. I'm not sure if the benefit of using the next > number in sequence would outweigh the performance penalty that would be > incurred.
The load as such for a rolling-your-own solution is about neglible. The case where you get problem is if the INSERT operation is part of a longer transaction. In this case, another attempt to insert can be blocked. If the number of inserts is high, you can get severe contention problems. On the oher hand, in our system we have plenty of tables where we don't use IDENTITY, including transactional ones. (We do have business requirements that some series must be sequential.) For the normal flow, this does not seem to cause much problems. Only where there is a batch operation, that runs for several minutes, you can see problems. -- Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se Books Online for SQL Server SP3 at
Jared Evans (jnevans@gmail.com) writes: [quoted text, click to view] > What would you recommend as a solution to keep the sequence contiguous? > Could you give an example of a such T-SQL function?
OK, I'm rewinding the thread, and repost this: BEGIN TRANSACTION SELECT @id = coalesce(MAX(id), 0) + 1 FROM tbl (UPDLOCK) WHERE type = @type INSERT tbl (id, type, ... VALUES (@id, @type, ... ... COMMIT TRANSACTION -- Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se Books Online for SQL Server SP3 at
ok, now it all makes sense to me. much thanks!
Don't see what you're looking for? Try a search.
|