Thread: Unique constraint over null values
Hi all, I have a table like CREATE TABLE a (type CHAR (1) NOT NULL,data1 CHAR (16) NOT NULL,data2 CHAR (16) NULL ); where type can be 's' for 'single' and 'x' for extended, so s should mean that there is only the type and data1 field, and x means that all fields are set. How can I set a unique constraint like CHECK (type = 's' AND UNIQUE (type, data1)) OR (type = 'x' AND UNIQUE (type, data1, data2)) ? The documentation says that 2 NULL values are different, so no unique constraint can be set over it. Thanks in advance, Thrasher
Thrasher, > where type can be 's' for 'single' and 'x' for extended, so s should > mean that there is only the type and data1 field, and x means that all > fields are set. > > How can I set a unique constraint like CHECK (type = 's' AND UNIQUE > (type, data1)) OR (type = 'x' AND UNIQUE (type, data1, data2)) ? > > The documentation says that 2 NULL values are different, so no unique > constraint can be set over it. Simple. Don't use NULLs. NULL means "unknown". You should use a differnent value, such as a blank string or "N/A" or "000000000000000" to represent "intentionally left blank". Then you can set data2 NOT NULL and use a regular UNIQUE constraint. BTW, you have defined your data columns as CHAR, not VARCHAR. You do know that this implies that your data columns will be *exactly* 16 characters in length? -- -Josh BerkusAglio Database SolutionsSan Francisco
Hi Josh, I think I'll follow your advice, as this is the method that I had in my pocket to use if I had no response. I tried with TRIM and other functions in the CHECK constraint, but I guess that I cannot use functions over a check field. It surprised me, but anyway, I'll do that. Thanks a lot for your prompt reply Thrasher Josh Berkus wrote: > Thrasher, > > >>where type can be 's' for 'single' and 'x' for extended, so s should >>mean that there is only the type and data1 field, and x means that all >>fields are set. >> >>How can I set a unique constraint like CHECK (type = 's' AND UNIQUE >>(type, data1)) OR (type = 'x' AND UNIQUE (type, data1, data2)) ? >> >>The documentation says that 2 NULL values are different, so no unique >>constraint can be set over it. > > > Simple. Don't use NULLs. NULL means "unknown". You should use a > differnent value, such as a blank string or "N/A" or "000000000000000" to > represent "intentionally left blank". > > Then you can set data2 NOT NULL and use a regular UNIQUE constraint. > > BTW, you have defined your data columns as CHAR, not VARCHAR. You do know > that this implies that your data columns will be *exactly* 16 characters in > length? >
Thrasher, > I think I'll follow your advice, as this is the method that I had in my > pocket to use if I had no response. I tried with TRIM and other > functions in the CHECK constraint, but I guess that I cannot use > functions over a check field. > > It surprised me, but anyway, I'll do that. > > Thanks a lot for your prompt reply No problem. You should also add a second constraint: CHECK ((type = 'x' AND data2 <> 'blank value') OR (type = 'y' AND data2 = 'blank value')) To enforce your other criterion. Keeop in mind that depending on the rest of your data structure, there are probably 8 different ways to approach this problem. I'd reccomend, in fact, a quick reading of Pascal's "Practical Issues in Database Management" on normalization to see the different table structures that might work for you. -- -Josh BerkusAglio Database SolutionsSan Francisco