How to create a unique index in a table so that it only has a record with a specific value in Sqlserver

Asked

Viewed 102 times

1

Hello, I am creating a data structure in Sqlserver and I have the following situation:

  • I have a list of contact types (person, public, commercial, etc...)
  • This list can be changed by the user but, obligatorily, it can only have 1 element as default.

The table structure looks like this:

create table TipoContato (
    id int not null identity(1,1),
    descricao nvarchar(100) not null,
    padrao bit not null constraint [DF_TipoContato.padrao] default 0
);
create unique index [UX_TipoContato.descricao] 
    on TipoContato(descricao);

Is there any way that I can force SQL to accept only a record as 1 for the default column? The intention is that if it is passed in a INSERT or UPDATE standard as 1, one must force all elements to be 0 beyond the informed.

Note: I have science that I can do this via TRIGGER, but I don’t see how the best possible way to do it... there’s a smarter way to solve the case?

  • 1

    What’s wrong with using the TRIGGER?

  • the problem is that in addition to not being directly attached to the table but to an external procedural structure, it makes it difficult to maintain the generation code of the tables...

1 answer

2


If the SQL Server version is higher than 2008, you can create a filtered index:

create table TipoContato (
    id int not null identity(1,1),
    descricao nvarchar(100) not null,
    padrao bit not null constraint [DF_TipoContato.padrao] default 0
);
create unique index [UX_TipoContato.descricao]  on TipoContato(descricao);
CREATE UNIQUE INDEX IX_padrao_unico ON TipoContato (padrao) WHERE padrao = 1;

If you try to do that:

insert into TipoContato  (descricao,padrao) values ('Test 1',0);
insert into TipoContato  (descricao,padrao) values ('Test 2',1);--padrao true
insert into TipoContato  (descricao,padrao) values ('Test 3',0);
insert into TipoContato  (descricao,padrao) values ('Test 4',0);
insert into TipoContato  (descricao,padrao) values ('Test 5',0);
insert into TipoContato  (descricao,padrao) values ('Test 6',0);
insert into TipoContato  (descricao,padrao) values ('Test 7',1);--erro

the second attempt to insert a true value for the default column will cause an error:

Cannot Insert Duplicate key Row in Object 'dbo.Tipocontato' with Unique index 'Ix_padrao_unico'. The Duplicate key value is (1).

See working on Sqlfiddle.

The idea is to capture the exception and act in some way. The standard column was set by error or was intentional?

Now if you want to always when the default column is set to true the former is amended to false, can’t get away from a Trigger.

  • That’s what I was wondering... unfortunately I know there’s no way to escape from a Rigger in cases like this, but what I can do is make an update before cleaning these references......

  • also, from what I’ve seen in the documentation, I can create multiplicity of relations between tables for the same column rs

Browser other questions tagged

You are not signed in. Login or sign up in order to post.