Как создать первичный ключ int на основе битового сдвига
Я работаю на сервере sql и VB.net. Я часто использую идентификатор (1,1) в первичном ключе int. Но сегодня я хочу создать таблицу, чтобы заменить перечисление. Я использую его в своей программе как флаги, которые можно добавить (это перечень болезней, до того, как я справился с несколькими болезнями, у вас может быть несколько болезней... но теперь я хочу быть в состоянии добавить больше болезней).
Я могу сделать это в моих кодах VB, но я предпочитаю, чтобы мой SQL-сервер сам позаботился о своих ключах. Но я не могу сказать, что следующий ключ = последний ключ << 1???
Спасибо за вашу помощь.
2 ответа
SQL Server не имеет оператора сдвига битов.
Для всего 15 записей, я бы рекомендовал просто использовать tinyint
в качестве основного ключа и вручную введите значения при вводе следующей строки.
Вы можете сделать так, чтобы SQL Server вычислял его автоматически для вас, но это излишне, чтобы делать это правильно.
Наивный подход будет примерно таким:
CREATE TABLE disease
(
ident tinyint identity(1,1),
name varchar(100),
id AS (POWER(2, ident)) PERSISTED PRIMARY KEY
)
Тестовое задание:
INSERT INTO disease (name) VALUES
('flu'), ('diabetes'), ('tonsillitis')
SELECT id, name
FROM disease
Результаты:
id name
2 flu
4 diabetes
8 tonsillitis
Но это наивно, потому что не предполагает пробелов в столбце идентичности. SQL Server не гарантирует этого вообще.
Для того, чтобы сделать это правильно, вам нужно будет вычислить столбец идентификатора, используя пользовательскую функцию, которая фактически посчитает количество записей, введенных до текущей, а затем вернет степень 2 на это число.
Обратите внимание, что в этом случае вычисляемый столбец не может сохраняться, поэтому он не может быть первичным ключом.
CREATE TABLE disease
(
ident tinyint identity(1,1) PRIMARY KEY,
name varchar(100),
);
GO
CREATE FUNCTION fn_CalculateDiseaseId
(
@ident tinyint
)
returns smallint
AS
BEGIN
RETURN
POWER(2,
(
SELECT COUNT(*)
FROM disease
WHERE ident < @ident
) +1
)
END;
GO
ALTER TABLE disease
ADD id AS dbo.fn_CalculateDiseaseId(ident);
GO
Тот же тест, что и раньше:
INSERT INTO disease (name) VALUES
('flu'), ('diabetes'), ('tonsillitis')
SELECT id, name
FROM disease
Результаты:
id name
2 flu
4 diabetes
8 tonsillitis
Начиная с SQL Server 2022, SQL поддерживает функции для получения/установки битов, смещения битов и подсчета битов. Они также существуют в базе данных SQL Azure. В режиме совместимости 160+ он также поддерживает << и >> для достижения побитового сдвига.