Поделиться через


Перенос вычисляемых столбцов

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

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

Непостоянные вычисляемые столбцы

Чтобы имитировать эффекты не сохраняемого вычисляемого столбца, создайте представление в оптимизированной для памяти таблице. В инструкции SELECT, определяющей представление, добавьте определение вычисляемого столбца в представление. За исключением скомпилированной в собственном коде хранимой процедуры, запросы, использующие значения из вычисляемого столбца, должны считываться из представления. Внутри собственно компилированных хранимых процедур следует обновить любое выражение SELECT, UPDATE или DELETE в соответствии с определением вычисляемого столбца.

-- Schema for the table dbo.OrderDetails:  
-- OrderId int not null primary key,  
-- ProductId int not null,  
-- SalePrice money not null,  
-- Quantity int not null,  
-- Total money not null  
--  
-- Total is computed as SalePrice * Quantity and is not persisted.  
CREATE VIEW dbo.v_order_details AS  
   SELECT  
      OrderId,  
      ProductId,  
      SalePrice,  
      Quantity,  
      Quantity * SalePrice AS Total  
   FROM dbo.order_details  

Сохраненные вычисляемые столбцы

Чтобы имитировать эффекты постоянно вычисляемого столбца, создайте хранимую процедуру для вставки в таблицу и другую хранимую процедуру для обновления таблицы. При вставке или обновлении таблицы вызовите эти хранимые процедуры для выполнения этих задач. В хранимых процедурах вычислите значение вычисляемого поля в соответствии с входными данными, например, как вычисляемый столбец определен в исходной таблице на основе диска. Затем вставьте или обновите таблицу в соответствии с необходимостью в хранимой процедуре.

-- Schema for the table dbo.OrderDetails:  
-- OrderId int not null primary key,  
-- ProductId int not null,  
-- SalePrice money not null,  
-- Quantity int not null,  
-- Total money not null  
--  
-- Total is computed as SalePrice * Quantity and is persisted.  
-- we need to create insert and update procedures to calculate Total.  
CREATE PROCEDURE sp_insert_order_details   
@OrderId int, @ProductId int, @SalePrice money, @Quantity int  
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER  
AS BEGIN ATOMIC WITH (LANGUAGE = N'english', TRANSACTION ISOLATION LEVEL = SNAPSHOT)  
-- compute the value here.   
-- this stored procedure works with single rows only.  
-- for bulk inserts, accept a table-valued parameter into the stored procedure  
-- and use an INSERT INTO SELECT statement.  
DECLARE @total money = @SalePrice * @Quantity  
INSERT INTO dbo.OrderDetails (OrderId, ProductId, SalePrice, Quantity, Total)  
VALUES (@OrderId, @ProductId, @SalePrice, @Quantity, @total)  
END  
GO  
  
CREATE PROCEDURE sp_update_order_details_by_id  
@OrderId int, @ProductId int, @SalePrice money, @Quantity int  
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER  
AS BEGIN ATOMIC WITH (LANGUAGE = N'english', TRANSACTION ISOLATION LEVEL = SNAPSHOT)  
-- compute the value here.   
-- this stored procedure works with single rows only.  
DECLARE @total money = @SalePrice * @Quantity  
UPDATE dbo.OrderDetails   
SET ProductId = @ProductId, SalePrice = @SalePrice, Quantity = @Quantity, Total = @total  
WHERE OrderId = @OrderId  
END  
GO  

См. также

Миграция на In-Memory OLTP