Сделать столбец получает 0 или 1 в зависимости от значения другого столбца

Я хочу знать, возможно ли создать столбец в таблице, который автоматически получает свое значение на основе значения другого столбца в той же таблице, пример ниже для пояснения:

CREATE TABLE dbo.example
(
    m_id INT NOT NULL CONSTRAINT PK_mid PRIMARY KEY IDENTITY (1,1),
    m_name NVARCHAR(30) NOT NULL,
    m_startdate DATE NOT NULL CONSTRAINT CHK_startdate CHECK(m_startdate <= SYSDATETIME()),
    m_enddate DATE CONSTRAINT CHK_enddate CHECK(m_enddate <= SYSDATETIME()),
    m_status INT CONSTRAINT CHK_status CHECK(m_status = 0 or m_status = 1)
)

Я хочу, чтобы m_status получал 0, если m_enddate имеет значение null, и 1, если оно не равно нулю. Это, конечно, будет при вставке строки.


person Matheus Faria    schedule 09.11.2016    source источник
comment
Насколько я знаю - так делать нельзя. То, что вы можете сделать, возможно, является триггером.   -  person sagi    schedule 09.11.2016
comment
пожалуйста, обратитесь к этой ссылке   -  person Husen    schedule 09.11.2016
comment
Действительно, единственный способ — через триггер (кстати, не только при INSERT, но и при UPDATE).   -  person FDavidov    schedule 09.11.2016


Ответы (3)


Вы можете использовать вычисляемый столбец следующим образом...

 CREATE TABLE dbo.example
(
m_id INT NOT NULL CONSTRAINT PK_mid PRIMARY KEY IDENTITY (1,1),
m_name NVARCHAR(30) NOT NULL,
m_startdate DATE NOT NULL CONSTRAINT CHK_startdate CHECK(m_startdate <= SYSDATETIME()),
m_enddate DATE CONSTRAINT CHK_enddate CHECK(m_enddate <= SYSDATETIME()),
m_status AS CASE
    WHEN m_enddate is null THEN 0 ELSE 1 
    END 
)
person Michael buller    schedule 09.11.2016

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

CREATE VIEW dbo.vwExample AS
  SELECT m_id,
         m_name,
         m_startdate,
         m_enddate,
         CASE WHEN m_enddate is null THEN 0 ELSE 1 END as m_status
  FROM   dbo.example

Теперь вы можете сделать

 select * from dbo.vwExample  

и у него будет правильное значение для m_status без необходимости изменять саму таблицу.

person GuidoG    schedule 09.11.2016

В T-SQL вы можете использовать триггеры вместо вставки/обновления, которые позволяют перехватывать вставки и обновления и внедрять логику.

CREATE TRIGGER dbo.exampleInsertTrigger
   ON   [dbo].[example]
   INSTEAD OF INSERT
AS 
BEGIN
INSERT INTO [dbo].[example]
    ([m_name]
    ,[m_startdate]
    ,[m_enddate]
    ,[m_status])
SELECT
    [m_name]
    ,[m_startdate]
    ,[m_enddate]
    ,CASE
    WHEN [m_enddate] is null THEN 0 ELSE 1 
    END
FROM inserted
END


CREATE TRIGGER dbo.exampleUpdateTrigger
   ON   dbo.example
   INSTEAD OF UPDATE
AS 
BEGIN
UPDATE [dbo].[example]
    SET
    [m_name] = inserted.[m_name]
    ,[m_startdate] = inserted.[m_startdate]
    ,[m_enddate] = inserted.[m_enddate]
    ,[m_status] = CASE
    WHEN inserted.[m_enddate] is null THEN 0 ELSE 1 
    END
FROM inserted
WHERE inserted.[m_id] = [dbo].[example].[m_id]
END
person Jeffrey Patterson    schedule 10.11.2016