Неверный синтаксис рядом с ключевым словом 'with'.
Здравствуйте, я пытаюсь понять, почему переключение режима совместимости с 80 на 100 в MSSQL нарушило мою функцию ниже?
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1617.0 (X64) Apr 22 2011 19:23:43
Copyright (c) Microsoft Corporation Express Edition with Advanced Services (64-bit) on
Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
Вот моя функция:
GO
ALTER FUNCTION [dbo].[GetRoot]
(
@Param1 int
)
RETURNS varchar(50)
AS
BEGIN
DECLARE @ReturnValue varchar(50)
with results as
(
select parentouid,net_ouid from net_ou where [email protected]
union all
select t2.parentouid,t2.net_ouid from net_ou t2
inner join results t1 on t1.parentouid = t2.net_ouid where t2.parentouid <> t1.net_ouid
)
select @ReturnValue = net_ou.displayname
from NET_OU RIGHT OUTER JOIN
results ON net_ou.net_ouid = results.ParentouID where results.parentouid=results.net_ouid
RETURN @ReturnValue
END
Ответы
Ответ 1
Попробуйте бросить полуколону перед с:
;with results as
(
select parentouid,net_ouid from net_ou where [email protected]
union all
select t2.parentouid,t2.net_ouid from net_ou t2
inner join results t1 on t1.parentouid = t2.net_ouid where t2.parentouid <> t1.net_ouid
)
Дайте эту статью, чтобы понять, зачем вам это нужно. Snipit:
Однако, если CTE не является первым оператором в партии, вы должны перед ключевым словом WITH укажите точку с запятой. Как наилучшая практика, я предпочитают префикс всех моих CTE точкой с запятой - я нахожу это более последовательный подход, чем необходимость помнить, нужна ли мне точка с запятой или нет.
Лично я не делаю этого для каждого CTE, но если это облегчит вам задачу, это ничего не повредит.
Ответ 2
Добавьте точку с запятой до WITH
:
;with results as
(
select parentouid,net_ouid from net_ou where [email protected]
union all
select t2.parentouid,t2.net_ouid from net_ou t2
inner join results t1 on t1.parentouid = t2.net_ouid where t2.parentouid <> t1.net_ouid
)
select @ReturnValue = net_ou.displayname
from NET_OU RIGHT OUTER JOIN
results ON net_ou.net_ouid = results.ParentouID where results.parentouid=results.net_ouid
RETURN @ReturnValue
END
Объявления CTE должны быть первой командой в пакете.
Ответ 3
Я бы предположил, что вы принимаете практику завершения всех операторов точкой с запятой. Это часть стандарта ANSI и поможет вам при необходимости работать с другой базой данных. SQL Server движется к этому в любом случае. В SQL Server 2012 еще много команд требуют точки с запятой.
например.
ALTER FUNCTION [dbo].[GetRoot]
(@Param1 int)
RETURNS varchar(50)
AS
BEGIN
DECLARE @ReturnValue VARCHAR(50)
;
WITH cteResults
AS (SELECT parentouid
,net_ouid
FROM net_ou
WHERE [email protected]
UNION ALL
SELECT t2.parentouid,t2.net_ouid
FROM net_ou t2
INNER JOIN results t1
ON t1.parentouid = t2.net_ouid
WHERE t2.parentouid <> t1.net_ouid )
SELECT @ReturnValue = net_ou.displayname
FROM net_ou
RIGHT JOIN cteResults
ON net_ou.net_ouid = results.ParentouID
WHERE results.parentouid=results.net_ouid
;
RETURN @ReturnValue
;
END
;
GO
В качестве дополнительного бонуса вы получаете запросы, которые легче читать.; -)