我需要在表值函数的主体内切换语言,以返回不同语言的月份名称和工作日。但是,当我尝试使用SET LANGUAGE RUSSIAN
时,我会收到Invalid use of a side-effecting operator 'SET COMMAND' within a function.
错误。
为什么在TVF中设置变量可以正常运行,而更改语言却会出错?我该如何在TVF中更改语言?
我需要在表值函数的主体内切换语言,以返回不同语言的月份名称和工作日。但是,当我尝试使用SET LANGUAGE RUSSIAN
时,我会收到Invalid use of a side-effecting operator 'SET COMMAND' within a function.
错误。
为什么在TVF中设置变量可以正常运行,而更改语言却会出错?我该如何在TVF中更改语言?
您不能在函数内使用 set language
。
您使用的是哪个版本?
如果是2012年及以后的版本,您可以执行以下操作:
SELECT FORMAT (GETDATE(), 'dddd', 'ru-RU'),
FORMAT (GETDATE(), 'MMMM', 'ru-RU')
在新版本中,你可以使用内置的函数替代。 (在回答的那天返回 вторник, Сентябрь
)。
在之前的版本中,你可以编写类似的CLR函数。
在2012版本之前,您可以使用sys.syslanguages
表来提取月份名称,例如:
CREATE VIEW dbo.MonthNameByLanguage
AS
WITH N1 AS (SELECT N FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (N)),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N1 AS N1 CROSS JOIN N1 AS N2)
SELECT l.langid,
languageName = l.name,
l.alias,
MonthNumber = ROW_NUMBER() OVER(PARTITION BY l.[langid] ORDER BY n.Number),
[MonthName] = SUBSTRING(l.months, n.Number, CHARINDEX(',', l.months + ',', n.Number) - n.Number)
FROM sys.syslanguages AS l
INNER JOIN Numbers AS n
ON (SUBSTRING(l.months, n.Number -1, 1) = ',' OR n.Number = 1);
这仅仅是从系统视图获取逗号分隔的月份名称,并使用一个数字表进行拆分。然后您可以将其用作函数内部的:
SELECT MonthName
FROM dbo.MonthNameByLanguage
WHERE alias = 'RUSSIAN'
AND MonthNumber = 3;
一般来说,我建议您尽可能晚地进行格式化。只需将日期传递给演示层,让区域设置处理格式即可。
对于星期几,您也可以采取类似的做法:
CREATE VIEW dbo.DayNameByLanguage
AS
WITH N1 AS (SELECT N FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (N)),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N1 AS N1 CROSS JOIN N1 AS N2)
SELECT l.langid,
languageName = l.name,
l.alias,
DayNumber = ROW_NUMBER() OVER(PARTITION BY l.[langid] ORDER BY n.Number),
[DayName] = SUBSTRING(l.days, n.Number, CHARINDEX(',', l.days + ',', n.Number) - n.Number)
FROM sys.syslanguages AS l
INNER JOIN Numbers AS n
ON (SUBSTRING(l.days, n.Number -1, 1) = ',' OR n.Number = 1);
FORMAT()
在这种情况下使您的生活变得更加轻松! - GarethD