Classic ASP 中 runnig UTF-8 编码 sql 文件的问题

Problems with runnig UTF-8 encoded sql files in Classic ASP

我有一堆 sql 文件,每次这些文件发生一些变化时,这些文件的查询不需要 运行 在我的本地数据库中。 我们使用经典的 ASP 代码将这些文件 运行 循环写入 VBScript,如下所示:

Dim arrSqlLines()
i = 0
set t = fso.OpenTextFile(filePath, 1, false)
Do Until t.AtEndOfStream
    Redim Preserve arrSqlLines(i)
    arrSqlLines(i) = t.ReadLine
    i = i + 1
Loop
t.close

For Each sqlLine in arrSqlLines
    sqlLine = Trim(sqlLine)
    sqlBatch = Trim(sqlBatch & sqlLine) & vbCrLf
    Call dbexecConnection(sqlBatch, objDbConnection)
Next

Function dbexecConnection(sql, objConnExec)
    dim cmdTemp
    on Error Resume Next
    set cmdTemp=Server.CreateObject("ADODB.Command")
    set cmdTemp.ActiveConnection=objConnExec
    cmdTemp.CommandText = sql

    cmdTemp.Execute
    if err.number<>0 Then
        if Session("SkipError") <> -1 Then
            response.write "Error in dbexecute: " & sql & "<br/>"
            response.write "Error=(" & err.description & ")"
            response.End
        end If
    end If
    on error goto 0
End Function

问题是,如果 sql 文件以 UTF-8 without BOM 编码,它 运行 没问题,但如果任何文件以 UTF-8 格式编码,它产生错误:

例如,这个 sql 文件的开头是这样的:

SET QUOTED_IDENTIFIER ON
GO

IF OBJECT_ID('RPM_GET_ACTUAL_COST_FOR_EPIC') IS NOT NULL
    DROP Function [RPM_GET_ACTUAL_COST_FOR_EPIC]
GO

CREATE Function [RPM_GET_ACTUAL_COST_FOR_EPIC]
(
    @EpicID as int,
    @RateType as Int, -- 1 for Blended, 2 for CostCenter
    @CalcType as Int -- 1 for by Hours or 2 for Points
)
returns float
BEGIN

declare @Cost float
declare @CostX float

declare @ItStorys TABLE (
    StorylD int,
    State int,
    DemoStatus int,
    Dfficulty int,
    Feature int,
    TeamID int,
    TrackType int,
    Iteration int
    )

insert into @tStorys(StoryID, State, DemoStatus, Dfficulty, Feature, TeamID, TrackType, Iteration) 

我不能保证所有文件都将以 UTF-8 without BOM 编码,所以我必须找到方法使它 运行 也正确地成为 UTF-8 文件。我怎么可能那样做?

只需告诉 Classic ASP 和 IIS 您想要使用 UTF-8 处理 ASP 页面。

首先保存 ASP 页面,确保使用代码页 65001 保存它(如果使用 Visual Studio 这可以通过 Advanced Save Options 菜单选项完成) .

然后修改 ASP 页面以包含以下初始行。

<%@Language="VBScript" CodePage = 65001 %>
<%
'Assuming this is the whole script the above line MUST always
'be the very first line in the source file.
'Tell ASP strings should be returned UTF-8 encoded.
Response.CodePage = 65001
'Tell the Browser to expect UTF-8 encoded data.
Response.Charset = "UTF-8"

Dim arrSqlLines()
i = 0
set t = fso.OpenTextFile(filePath, 1, false)
Do Until t.AtEndOfStream
    Redim Preserve arrSqlLines(i)
    arrSqlLines(i) = t.ReadLine
    i = i + 1
Loop
t.close

For Each sqlLine in arrSqlLines
    sqlLine = Trim(sqlLine)
    sqlBatch = Trim(sqlBatch & sqlLine) & vbCrLf
    Call dbexecConnection(sqlBatch, objDbConnection)
Next

Function dbexecConnection(sql, objConnExec)
    dim cmdTemp
    on Error Resume Next
    set cmdTemp=Server.CreateObject("ADODB.Command")
    set cmdTemp.ActiveConnection=objConnExec
    cmdTemp.CommandText = sql

    cmdTemp.Execute
    if err.number<>0 Then
        if Session("SkipError") <> -1 Then
            response.write "Error in dbexecute: " & sql & "<br/>"
            response.write "Error=(" & err.description & ")"
            response.End
        end If
    end If
    on error goto 0
End Function
%>

有用的链接

  • Convert UTF-8 String Classic ASP to SQL Database

可以肯定的是,FileSystemObject 不处理 UTF-8,而是处理 Unicode 和 ANSI。
ADODB.Stream 可以处理很多字符集,包括 utf-8,因此您可以改用它。
用以下代码替换第一个 For 之前的代码。

Dim arrSqlLines
With Server.CreateObject("Adodb.Stream")
    .Charset = "utf-8"
    .Open
    .LoadFromFile filePath
    If .EOS Then
        'an empty array if file is empty
        arrSqlLines = Array()
    Else
        'to obtain an array of lines like you desire
        'remove carriage returns (vbCr) if exist 
        'and split the text by using linefeeds (vbLf) as delimiter
        arrSqlLines = Split(Replace(.ReadText, vbCr, ""), vbLf)
    End If
    .Close
End With