Не используйте триггер для этого. Вам будет лучше с отфильтрованным уникальным индексом:
CREATE UNIQUE INDEX UQ_one_cicloEstado
ON dbo.ciclo_OI (cicloEstado)
WHERE cicloEstado = 1;
Пример:
CREATE TABLE dbo.TestTable (ID int IDENTITY,
SomeInt int,
SomeString varchar(10));
CREATE UNIQUE INDEX UQ_one_SomeInt
ON dbo.TestTable (SomeInt)
WHERE SomeInt = 1;
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(1,'asdkasd'); --Works.
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(2,'asdfgdf'); --Works.
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(1,'sdfsdf'); --Fails.
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(2,'etrytrg'); --Works.
GO
SELECT *
FROM dbo.TestTable;
GO
DROP TABLE dbo.TestTable;
Поскольку ОП на самом деле хочет 2 строки, то вышеприведенное неверно, но я оставил это там.
Триггер все еще не лучшее место для этого, на мой взгляд, но (к сожалению), которое оставляет нам только многострочную скалярную функцию. Далеко от идеала, и этот может пострадать из-за условий гонки, но я подозреваю (из-за "правила 2"), что это маловероятно. Вот пример:
CREATE TABLE dbo.TestTable (ID int IDENTITY,
SomeInt int,
SomeString varchar(10));
GO
CREATE FUNCTION dbo.CheckInt1Count()
RETURNS INT
AS BEGIN
DECLARE @Count int = 0;
SELECT @Count = COUNT(*)
FROM dbo.TestTable
WHERE SomeInt = 1;
RETURN @Count;
END;
GO
ALTER TABLE dbo.TestTable ADD CONSTRAINT ck_int1Count CHECK (dbo.CheckInt1Count() <= 2);
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(1,'asdkasd'); --Works.
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(2,'asdfgdf'); --Works.
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(1,'sdfsdf'); --Works.
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(2,'etrytrg'); --Works.
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(1,'jdgfhbsk'); --Fails.
GO
GO
INSERT INTO dbo.TestTable (SomeInt,
SomeString)
VALUES(2,'sdfipasdf'); --Works.
GO
SELECT *
FROM dbo.TestTable;
GO
DROP TABLE TestTable;
DROP FUNCTION dbo.CheckInt1Count;