Невозможно сохранить вычисляемый столбец-не детерминированный
у меня есть эта функция для вычисляемого столбца:
CREATE FUNCTION [dbo].[GetAllocatedStartTime](@Year INT, @Week INT)
RETURNS DATETIME
WITH schemabinding
AS BEGIN
RETURN dateadd(week,@Week-(1),dateadd(day,(-1),dateadd(week,datediff(week,(0),CONVERT([varchar](4),@Year,(0))+'-01-01'),(1))))
END
GO
добавил WITH schemabinding
в надежде, что это сделает его детерминированным, чтобы я мог его сохранить. Это должно быть как два входа [Week]
и [Year]
всегда будет давать одни и те же результаты.
код ошибки :
вычисляемый столбец "AllocatedTimeStart" в таблице "Tmp_Bookings" не может быть сохранен, так как столбец недетерминированный.
я использую эту формулу в столбец :
([dbo].[GetAllocatedStartTime]([Year],[Week]))
и столбец defs:
[Week] [int] NOT NULL,
[Year] [int] NOT NULL,
[AllocatedTimeStart] AS ([dbo].[GetAllocatedStartTime]([Year],[Week])),
какие идеи?
EDIT:
изменить строки :
RETURN dateadd(week,@Week-(1),dateadd(day,(-1),dateadd(week,datediff(week,(0),CONVERT(datetime,CONVERT([varchar](4),@Year,(0))+'0101',112)),(1))))
но теперь я получаю ошибку, говоря, что формула для столбца недействительна. Хотя функция сохраняет отлично.
EDIT 2:
я показал, что именно я делать (или, по крайней мере, я пробовал). На самом деле нет ничего лишнего. Как говорится в предыдущей функции (исходной) в сочетании с формулой ref [dbo].AllocatedStartDate(...)
чтобы он в колонке работал, но не настаивал, он сказал, что он не детерминирован. Поэтому в соответствии с предложением я изменил функцию, заменив часть преобразования новым кодом, поэтому функция теперь выглядит так:
FUNCTION [dbo].[GetSTime](@Year INT, @Week INT)
RETURNS DATETIME
WITH schemabinding
AS BEGIN
RETURN dateadd(week,@Week-(1),dateadd(day,(-1),dateadd(week,datediff(week,(0),CONVERT(datetime,CONVERT([varchar](4),@Year,(0))+'0101',112)),(1))))
END
затем я попробовал ту же формулу, что и раньше в вычисляемом поле (([dbo].[GetAllocatedStartTime]([Year],[Week])))
... и он отвергает формула говорит, что она недействительна... что странно, поскольку формула одинакова, поэтому она должна выполнять какую-то проверку измененной функции и находить ее недействительной, что также странно, потому что я сделал plain SELECT dbo.GetAllocatedStartTime(2012,13)
и это сработало...
так что да, я запутался, и я никогда не видел SqlFiddle
неважно, используйте его. Но на самом деле нет ничего более, что я только что сказал.
1 ответов
CONVERT([varchar](4),@Year,(0))+'-01-01'
передается DATEDIFF
вызова, в позиции, где ожидается дата, заставляя неявное преобразование происходит.
из правил для детерминированные функции:
CAST
детерминированным, если не используется с
datetime
,smalldatetime
илиsql_variant
.
CONVERT
детерминированный, если только одно из этих условий не существует:
...
тип источника или цели
datetime
илиsmalldatetime
, другим исходным или целевым типом является символьная строка и указывается недетерминированный стиль. Чтобы быть детерминированным, параметр style должен быть константой. Кроме того, стили, меньшие или равные 100, являются недетерминированными, за исключением стилей 20 и 21. Стили более 100 являются детерминированными, за исключением стилей 106, 107, 109 и 113.
Ну, вы не звоните ни тому, ни другому, но вы полагаетесь на неявное преобразование, которое я ожидал бы действовать как CAST
. Вместо того, чтобы полагаться на это, я бы переключился на использование CONVERT
и дайте детерминированный параметр стиля.
Итак, я делаю: CONVERT(datetime,CONVERT([varchar](4),@Year,(0))+'0101',112)
в своем месте. После этого сама функция становится детерминированной