【问题标题】:Writing nvarchar to a text file将 nvarchar 写入文本文件
【发布时间】:2018-06-16 13:57:22
【问题描述】:

我在写入文本文件时遇到问题。当我的文本是 ASCII 时,一切正常:

DECLARE @OLE INT
DECLARE @FileId INT
DECLARE @File VARCHAR(max) = 'D:\test.txt'
DECLARE @Text NVARCHAR(max) = N'no problem when writing in english!'

EXECUTE sp_OACreate 'Scripting.FileSystemObject',@OLE OUT
EXECUTE sp_OAMethod @OLE, 'OpenTextFile', @FileId OUT, @File,2,1
EXECUTE sp_OAMethod @FileId, 'WriteLine', Null, @Text

但是当我的文本包含 Unicode 字符时,文件中不会出现任何内容:

DECLARE @Text NVARCHAR(max) = N'من نمایش داده نمیشم'

我也试过sp_OASetProperty,但没用(mentioned here):

EXECUTE sp_OASetProperty @OLE, 'Charset', 'UTF-8'  

有解决此问题或使用其他 T-SQL 过程的想法吗?

【问题讨论】:

  • 如果你想要 UTF-8 而不是 UTF-16,VBScripters 使用“ADODB.Stream”对象。 (不过,我从未在 SQL 中使用过它,而 sp_OACreate 对我来说是新的。SQLCLR 将是我的首选。)

标签: sql sql-server tsql unicode


【解决方案1】:
EXECUTE  @HR = sp_OACreate 'ADODB.Stream',  @OLE OUTPUT

EXECUTE sp_OASetProperty    @OLE,    'Type',    2                    
EXECUTE sp_OASetProperty    @OLE,    'Mode',    3                    
EXECUTE sp_OASetProperty    @OLE,    'Charset',  'Windows-1256'   
EXECUTE sp_OASetProperty    @OLE,    'LineSeparator',    'adLF'
EXECUTE sp_OAMethod         @OLE,    'Open'  
EXECUTE sp_OAMethod         @OLE,  'WriteText',  NULL,   @String  
 
--Commit data and close text stream
 EXECUTE sp_OAMethod  @OLE,'SaveToFile', NULL, @FileAndPath, 2  
 EXECUTE sp_OAMethod   @OLE,  'Close'
 EXECUTE  sp_OADestroy   @OLE

【讨论】:

    【解决方案2】:

    根据Scripting.FileSystemObject documentationCreateTextFile 方法采用布尔值来创建 Unicode 文件。您可以更改 T-SQL 代码以使用该方法而不是 OpenTextFile

    编辑:

    以下是根据 Tom 的评论使用 OpenTextFile 的示例。我将原始代码中的 iomode 值从 1 更改为 8 以匹配文档,并添加关闭和销毁以防您的完整代码缺少这些重要任务。

    DECLARE @OLE INT;
    DECLARE @FileId INT;
    DECLARE @File VARCHAR(max) = 'c:\test.txt';
    DECLARE @Text NVARCHAR(max) = N'من نمایش داده نمیشم';
    
    EXECUTE sp_OACreate 'Scripting.FileSystemObject',@OLE OUT;
    EXECUTE sp_OAMethod @OLE, 'OpenTextFile', @FileId OUT, @File,8,1,-1;
    EXECUTE sp_OAMethod @FileId, 'WriteLine', Null, @Text;
    EXECUTE sp_OAMethod @FileId, 'Close';
    EXECUTE sp_OADestroy @FileId OUT;
    EXECUTE sp_OADestroy @OLE OUT;
    

    【讨论】:

    • OpenTextFile 确实有类似的论点。顺便说一句——NVARCHAR 表示 UTF-16,而 FileSystemObject 上下文中的 Unicode 也表示 UTF-16。不过,重要的部分是 VBScript 字符串也是 UTF-16,因此将 NVARCHAR 值传递给 FileSystemObject 函数是正确的参数类型。对于输出,指示 Unicode 将产生一个 UTF-16 编码的文件。
    猜你喜欢
    • 1970-01-01
    • 2017-09-27
    • 2018-08-23
    • 1970-01-01
    • 2012-12-08
    • 2016-10-20
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多