如何在T-SQL表值函数内切换语言

时间:2015-09-08 11:46:42

标签: sql-server tsql user-defined-functions

我需要在表值函数体内的语言之间切换,以不同的语言返回月份名称和工作日。但是当我尝试使用SET LANGUAGE RUSSIAN时,我收到Invalid use of a side-effecting operator 'SET COMMAND' within a function.错误。

为什么在TVF中设置变量时会发生这种情况?如何更改TVF内的语言?

2 个答案:

答案 0 :(得分:4)

您不能在函数中使用set language

你在哪个版本?

如果2012+你可以做到

SELECT FORMAT (GETDATE(), 'dddd', 'ru-RU'), 
       FORMAT (GETDATE(), 'MMMM', 'ru-RU')

代替。 (在回答当天返回вторник, Сентябрь。)

在以前的版本中,您可以编写类似的CLR函数。

答案 1 :(得分:3)

在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);