【问题标题】:Bulk Insert Russian & other international Characters into SQL Server 2008将俄语和其他国际字符批量插入 SQL Server 2008
【发布时间】:2015-09-03 09:55:35
【问题描述】:

当我在制表符分隔文件(从 UNIX SAP 系统导出)上使用批量插入到 SQL Server 2008 R2 中时,如果 Short_text 字段是像俄语这样的扩展字符,它们会变成象形文字。

我的代码是:

    BULK INSERT ProcureDB.dbo.tbl_SAP_PO_Load
    FROM \\Path\'Bulk_Insert_test.txt'
    WITH
    (
       FIELDTERMINATOR = '\t'
      ,FIRSTROW=2
      ,ROWTERMINATOR = '0x0a')

这是短文本字段的外观:

Short_Text
стаканы одноразовые                                                                                                                 
чай черный                                                                                                                          
Dell 22" Touch screen                                                                                                                   
Dell 3 yr advanced exchange svc

前两行是俄语。如果我使用文本导入向导将其导入 Excel,默认情况下它使用代码页 65001(65001:Unicode (UTF-8) 并且俄语文本在 Excel 表中显示正常

Short_Text (in excel sheet)
стаканы одноразовые                                                                                                                 
чай черный                                                                                                                          
Dell 22" Touch screen                                                                                                                   
Dell 3 yr advanced exchange svc 

网络上的一个建议是在批量插入中使用代码页 65001。

因此代码:

    BULK INSERT ProcureDB.dbo.tbl_SAP_PO_Load
    FROM \\Path\'Bulk_Insert_test.txt'
    WITH
    (
       **CODEPAGE = '65001'**
      ,FIELDTERMINATOR = '\t'
      ,FIRSTROW=2
      ,ROWTERMINATOR = '0x0a')

但是这会产生错误:

消息 2775,第 16 级,状态 13,第 3 行
服务器不支持代码页 65001。

如何获得服务器支持的代码页 65001?

另一个建议是使用 CODEPAGE = 'ACP'。这是可行的,但是,俄语字符已损坏,但方式不同。

Short_Text
Ñтаканы одноразовые                                                                                                                 
чай черный                                                                                                                          
Dell 22" Touch screen                                                                                                                   
Dell 3 yr advanced exchange svc    

版本信息。如下:

  • Microsoft SQL Server 标准版(64 位)10.50.6000.34
  • Microsoft Windows NT 6.1 (7601) NT x64
  • 英语(美国)
  • SQL_Latin1_General_CP1_CI_AS

【问题讨论】:

    标签: database excel sql-server-2008 import


    【解决方案1】:

    当我遇到同样的问题时,我创建了自己的解决方法。我正在导入的 UTF-8 文本文件是由另一个应用程序创建/更新的,所以我无法更改文件格式。

    1. 我的数据库有排序规则Cyrillic_General_CI_AS
    2. 将包含俄语的所有列都声明为nchar()nvarchar()
    3. 我将BULK INSERT我的制表符分隔的文本文件放入临时表中:

      截断表 tempTable 从 'C:\Users...\MyFile.txt' 批量插入 tempTable with(DATAFILETYPE = 'char', FIELDTERMINATOR = '\t', FIRSTROW = 2,代码页 = 1251)

    因此,我得到的字段如下所示:

    АБВГДЕЁЖЗРЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯР
    
    1. 为了解码,我创建了一个表和一个函数:

      declare @Codes char(200), @Letters char(100)
      if exists(select * from sys.objects where name = 'bDecode') 
      drop table bDecode
      create table bDecode(Code nvarchar(2), Letter nvarchar(1))
      set @Codes = 
      'АБВГДЕЁЖЗРЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя'
      set @Letters = 
      'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя'
      declare @i int set @i = 1 while @i <= len(@Letters) 
      begin
          insert into bDecode(Code, Letter) 
          select  substring(@Codes, @i * 2 - 1, 2),
                  substring(@Letters,@i,1)
          set @i = @i + 1
      end
      GO
          CREATE FUNCTION [dbo].[fn_Decode](@Name nvarchar(500)) returns nvarchar(500) as BEGIN 
      
      --select top 10 * from tmpAuthors
      --declare @Name nvarchar(500) set @Name = 'АБВГДЕЁЖЗРЙКЛМНОП'
      
          declare @i int, @NameCode nchar(2), @TableCode nchar(2), @Letter nchar(1)
      
          set @i = 1 while @i < len(@Name) begin
      
              set @NameCode = substring(@Name,@i,2)
      
              if exists(select 1 from bDecode where Code = @NameCode 
                  and unicode(right(Code,1)) = unicode(right(@NameCode,1))) begin
      --print @Name
                  select @TableCode = Code, @Letter = Letter 
                  from bDecode where Code = @NameCode
                      and unicode(right(Code,1)) = unicode(right(@NameCode,1))
      
                  set @Name = left(@Name, @i - 1) + @Letter + right(@Name, len(@Name) - @i - 1)
              end
      
          set @i = @i + 1 end
      
      --print @Name
      
      --------------------------------------------
      
          RETURN @Name
      END
      GO
      
    2. 现在我执行解码:

      update tempTable set Name = dbo.fn_Decode(Name)
      

    这对我有用。

    【讨论】:

    • 请整理一下,这样你想说的话就可以理解了。
    • 我试图格式化这个答案,当所有代码都放在代码块中时,编辑器不允许保存它......
    猜你喜欢
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多