如何在 T-SQL table 值函数内切换语言
How to switch languages inside T-SQL table-valued function
我需要在 table 值函数主体内的语言之间切换为不同语言的 return 月份名称和工作日。但是当我尝试使用 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')
相反。 (回答当天 Returns вторник, Сентябрь
)。
在以前的版本中,您可以编写类似的 CLR 函数。
在 2012 之前的版本中,您可以使用 sys.syslanguages
table 来提取月份名称,例如
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);
这只是从系统视图中获取逗号分隔的月份名称,并使用数字 table 将其拆分出来。然后你可以在你的函数中使用它:
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);
我需要在 table 值函数主体内的语言之间切换为不同语言的 return 月份名称和工作日。但是当我尝试使用 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')
相反。 (回答当天 Returns вторник, Сентябрь
)。
在以前的版本中,您可以编写类似的 CLR 函数。
在 2012 之前的版本中,您可以使用 sys.syslanguages
table 来提取月份名称,例如
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);
这只是从系统视图中获取逗号分隔的月份名称,并使用数字 table 将其拆分出来。然后你可以在你的函数中使用它:
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);