условное ограничение на уникальность данных

Сообщение об ошибке информирует вас о проблеме: версия диспетчера развертывания (8.5.5.2) более ранняя, чем версия агента узла (8.5.5.13)

Сначала следует обновить диспетчер развертывания, он должен быть на том же или более новом уровне обслуживания, что и узлы в соте.

87
задан faintsignal 23 November 2016 в 22:19
поделиться

5 ответов

Add a check constraint like this. The difference is, you'll return false if Status = 1 and Count > 0.

http://msdn.microsoft.com/en-us/library/ms188258.aspx

CREATE TABLE CheckConstraint
(
  Id TINYINT,
  Name VARCHAR(50),
  RecordStatus TINYINT
)
GO

CREATE FUNCTION CheckActiveCount(
  @Id INT
) RETURNS INT AS BEGIN

  DECLARE @ret INT;
  SELECT @ret = COUNT(*) FROM CheckConstraint WHERE Id = @Id AND RecordStatus = 1;
  RETURN @ret;

END;
GO

ALTER TABLE CheckConstraint
  ADD CONSTRAINT CheckActiveCountConstraint CHECK (NOT (dbo.CheckActiveCount(Id) > 1 AND RecordStatus = 1));

INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 1);

INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 1);
INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 2);
-- Msg 547, Level 16, State 0, Line 14
-- The INSERT statement conflicted with the CHECK constraint "CheckActiveCountConstraint". The conflict occurred in database "TestSchema", table "dbo.CheckConstraint".
INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 1);

SELECT * FROM CheckConstraint;
-- Id   Name         RecordStatus
-- ---- ------------ ------------
-- 1    No Problems  2
-- 1    No Problems  2
-- 1    No Problems  2
-- 1    No Problems  1
-- 2    Oh no!       1
-- 2    Oh no!       2

ALTER TABLE CheckConstraint
  DROP CONSTRAINT CheckActiveCountConstraint;

DROP FUNCTION CheckActiveCount;
DROP TABLE CheckConstraint;
36
ответ дан 24 November 2019 в 07:46
поделиться

Вы можете переместить удаленные записи в таблицу, в которой отсутствует ограничение, и, возможно, использовать представление с UNION двух таблиц, чтобы сохранить внешний вид одной таблицы.

10
ответ дан 24 November 2019 в 07:46
поделиться

Вы можете сделать это по-настоящему хакерским способом ...

Создайте представление таблицы на основе схемы.

СОЗДАТЬ ПРОСМОТР Что угодно ВЫБРАТЬ * ИЗ таблицы WHERE RecordStatus = 1

Теперь создайте уникальное ограничение для представления с нужными полями.

Одно замечание о представлениях, связанных со схемой: если вы измените базовые таблицы, вам придется воссоздать представление. Из-за этого много подводных камней.

3
ответ дан 24 November 2019 в 07:46
поделиться

Если вы не можете использовать NULL в качестве RecordStatus, как предложил Билл, вы можете объединить его идею с индексом на основе функций. Создайте функцию, которая возвращает NULL, если RecordStatus не является одним из значений, которые вы хотите учитывать в своем ограничении (и RecordStatus в противном случае), и создайте индекс над этим.

Это даст преимущество, которого у вас нет. чтобы явно исследовать другие строки в таблице в вашем ограничении, что может вызвать проблемы с производительностью.

Я должен сказать, что я вообще не знаю SQL-сервер, но я успешно использовал этот подход в Oracle.

1
ответ дан 24 November 2019 в 07:46
поделиться

Поскольку вы собираетесь разрешить дублирование, уникальное ограничение не будет работать. Вы можете создать ограничение проверки для столбца RecordStatus и хранимую процедуру для INSERT, которая проверяет существующие активные записи перед вставкой повторяющихся идентификаторов.

1
ответ дан 24 November 2019 в 07:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: