0

有一些最初为 Oracle 编写的代码已转换为使用 SQL Server。但是,法国目前存在一个问题,日期名称以英文显示。这是因为 CONVERT 用于更改格式,但SET LANGUAGE不用于更改会话的语言(而在 Oracle 语言中作为to_char提供等效转换的函数的一部分包含在内)。

更深入地看,我相信SET LANGUAGE没有使用,因为代码在函数中 - 因为set有副作用,所以不能包含在其中。

有谁知道解决这个问题的方法;即更改函数中单个语句的语言,而不是影响整个会话?

编辑

为了更好地说明我的问题,想象一下尝试在 SQL 中重新创建 Oracle 功能 - 例如如下所示。

--this won't work because SET LANGUAGE affects the state of the session; 
create function dbo.to_char(@date datetime, @format nvarchar(32), @language nvarchar(32))
returns nvarchar(32)
as 
begin
      declare @result nvarchar(32)
      , @formatSql int

      --here we need to map the available Oracle options to their SQL equivs
      --SQL is more restrictive in that it uses predefined date formats rather than masks
      --I can't recall the typical valid oracle format masks - but just append to this those that you use
      set @formatSql = 
      case @format
            when 'dd mon yyyy' then 106
            when 'mon dd yyyy' then 107
            when 'dd/mm/yyyy'  then 103
            when 'mm/dd/yyyy'  then 101
            else 121 --default to yyyy-mm-dd hh:mi:ss.mmm(24h)
      end

      select @language = REPLACE(@language,'NLS_DATE_LANGUAGE','')
      , @language = REPLACE(@language,'=','')
      , @language = REPLACE(@language,' ','')

      set language @language 

      set @result = CONVERT(nvarchar(32), @date, @formatSql)

      set language English --revert session language

      return @result
end
go


select dbo.to_char(getutcdate(), 'dd mon yyyy', 'NLS_DATE_LANGUAG = French') --from dual ;)

提前致谢。

4

1 回答 1

1

此代码将在一个函数中运行,并为您提供一个表格,其中包含每个月的数字和大写法语缩写。然后,您可以使用它来构建您的格式化日期。

Declare @months varchar(200)

select @months = shortmonths
from sys.syslanguages
where lcid = 1036 --i.e. French

Declare @individual varchar(20) = null
declare @monthsTable table (monthNumber int identity(1,1), name nvarchar(20))

WHILE LEN(@months) > 0
BEGIN
    IF PATINDEX('%,%',@months) > 0
    BEGIN
        SET @individual = SUBSTRING(@months, 0, PATINDEX('%,%',@months))
        SET @months = SUBSTRING(@months, LEN(@individual + ',') + 1, LEN(@months))
    END
    ELSE
    BEGIN
        SET @individual = @months
        set @months = null
    END
    insert into @monthsTable(name) select UPPER(@individual) 
END

出于好奇,您是否有理由不在前端执行此操作?Sql 并不真正适合格式化任务。

于 2013-10-18T16:18:09.133 回答