| |
|
If this is your first visit, be sure to check out the FAQ by clicking the link above.
You may have to register before you can post: click the register link above to proceed.
To start viewing messages, select the forum that you want to visit from the selection below.
|
 |

02-22-10, 02:31
|
|
Registered User
|
|
Join Date: Apr 2002
Posts: 84
|
|
To make a non-key field unique
|
|
Dear All,
I encountered a tricky problem, a non-key field (string type) must be unique. It is with the format of YYYY-Order_No, while YYYY is current year and Order_No should be incremental. We use '2010' || '-' || 1+Select count (*) from Order_table to generate the string.
The problem is, when there are two persons access to the query at the same time, the value will be duplicated. Any solution? As it is already a production database, we cannot change much on the schema.
Thanks!
XZ
|
|

02-22-10, 02:57
|
|
Registered User
|
|
Join Date: Dec 2005
Posts: 273
|
|
create an unique index on that field.
If two user try to insert the same value, the second one will fail and can ( automaticly ) recalculate the Orderno and retry the insert
|
|

02-22-10, 03:44
|
|
Registered User
|
|
Join Date: Apr 2002
Posts: 84
|
|
|
|
The problem is we have some historical data with null values in the field. Any solution?
Thanks.
Quote:
Originally Posted by umayer
create an unique index on that field.
If two user try to insert the same value, the second one will fail and can ( automaticly ) recalculate the Orderno and retry the insert
|
|
|

02-22-10, 04:02
|
|
Registered User
|
|
Join Date: Dec 2005
Posts: 273
|
|
in that case: create an UNIQUE WHERE NOT NULL index ...
|
|

02-22-10, 06:08
|
|
Registered User
|
|
Join Date: Feb 2008
Location: Japan
Posts: 2,194
|
|
"WHERE NOT NULL" is supported on DB2 for z/OS and iSeries.
It is not supported on DB2 for LUW.
|
|

02-22-10, 07:47
|
|
Registered User
|
|
Join Date: Jan 2007
Location: Jena, Germany
Posts: 2,662
|
|
We don't know on which product the OP is working. So if it is indeed DB2 LUW, one option would be to add a trigger that does the weak uniqueness checks.
__________________
Knut Stolze
IBM DB2 Analytics Accelerator
IBM Germany Research & Development
|
|

02-22-10, 10:00
|
|
Registered User
|
|
Join Date: Nov 2005
Location: IL
Posts: 554
|
|
you said you already have historical data in there and some of it is NULL. If you have more then one record where this data is NULL you are SOL as you can only have one NULL in your UNIQUE index. You would have no other choice but to do table redesign like it or not.
Run a SQl to find out if you have more then one NULL. Sounds like you will.
__________________
--
IBM Certified DBA on DB2 for Linux, UNIX, and Windows
DB2 v9.1.0.2 os 5.3.0.0
|
|

02-22-10, 10:37
|
|
Registered User
|
|
Join Date: Jul 2009
Location: NY
Posts: 886
|
|
You can use something like this:
Code:
select char(year(current date)) || '-' ||char(coalesce(count (*), 0) + 1 )
from Order_table
Lenny
|
|

02-22-10, 11:38
|
|
Registered User
|
|
Join Date: Dec 2008
Location: Toronto, Canada
Posts: 381
|
|
Quote:
Originally Posted by qxz
Dear All,
I encountered a tricky problem, a non-key field (string type) must be unique. It is with the format of YYYY-Order_No, while YYYY is current year and Order_No should be incremental. We use '2010' || '-' || 1+Select count (*) from Order_table to generate the string.
The problem is, when there are two persons access to the query at the same time, the value will be duplicated. Any solution? As it is already a production database, we cannot change much on the schema.
Thanks!
XZ
|
i think you should had have 2 cols - year and order_number - and make order_number an indentity column. Will work much much faster. you wll not get dups. Select count (*) is bad in the first place - takes too long. And I agree with Cougar8000 - you need to re-design it.
In order to keep the NULLs if there is more than one, you can
- create another table with same structure but allowing NULLs in order_num col
- move all records with NULLs to this table
- alter original table to make order_number an identity col
- create a view on both tables with union all
- make users to use the view (if it has same name as original table they will not notice any difference )
__________________
DB2 v9.5 ESE on AIX v6.1/ v9./10 on z/OS
|
Last edited by MarkhamDBA; 02-22-10 at 11:49.
|

02-22-10, 11:48
|
|
Registered User
|
|
Join Date: Nov 2005
Location: IL
Posts: 554
|
|
I totally missed it the first time. You are doing this for every new record?
Quote:
|
'2010' || '-' || 1+Select count (*) from Order_table
|
How is your performance?
__________________
--
IBM Certified DBA on DB2 for Linux, UNIX, and Windows
DB2 v9.1.0.2 os 5.3.0.0
|
|

02-22-10, 12:02
|
|
Registered User
|
|
Join Date: Dec 2008
Location: Toronto, Canada
Posts: 381
|
|
we have one of those - instead of using identity col or a sequence, they created a trigger which finds max(col), adds 1 and inserts it into the table. performance is awful. we are going to change it to identitly column as soon as we can.
__________________
DB2 v9.5 ESE on AIX v6.1/ v9./10 on z/OS
|
|

02-23-10, 12:31
|
|
Registered User
|
|
Join Date: Apr 2002
Posts: 84
|
|
Thanks for all the help.
What should I do if there is some condition, for example, to get the number of orders of a particular product. How to optimize a query like:
> select count(*) from Order_Table where product_id = 'abc'?
Quote:
Originally Posted by MarkhamDBA
we have one of those - instead of using identity col or a sequence, they created a trigger which finds max(col), adds 1 and inserts it into the table. performance is awful. we are going to change it to identitly column as soon as we can.
|
|
|

02-24-10, 09:44
|
|
Registered User
|
|
Join Date: Dec 2007
Location: Richmond, VA
Posts: 782
|
|
put an index on product_id
|
|

02-24-10, 14:58
|
|
Registered User
|
|
Join Date: Dec 2008
Location: Toronto, Canada
Posts: 381
|
|
BTW if you insist on using '1+Select count (*)' to get a value for next order_no, I think it's better change it to 'max(order_no)' or you are skipping numbers because your count(*) counts NULL values too. For example, if you have 100 records and 10 of them are NULLs, your next order_no will be 101 (not 91) though your max order_no might be =90.
__________________
DB2 v9.5 ESE on AIX v6.1/ v9./10 on z/OS
|
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|