0

我有一个 VB6 应用程序,当尝试保存 unicode 字符时,这些字符没有正确保存在 Ms SQL 数据库中。直接在 SSMS 中执行插入语句时,插入正确执行。

Exec sp_Insert_item 1, 101, N'Ħass'

我在连接字符串中使用 SQLOLEDB 作为驱动程序,并且我的列设置为 NVarchar

有谁知道如何解决这个问题?

谢谢,艾伦

4

2 回答 2

0

您是正确的,VB6 将支持 unicode。事实上,VB6 字符串本质上是 unicode,但问题是当从不正确支持它的用户控件显示/检索时,它会在翻译中丢失。

如果您从 UI 获取字符串,请确保使用支持它的文本框控件。例如,添加对 Microsoft Forms 2.0 对象库的引用,并在开箱即用的常规文本框控件上使用这些控件。这样,您可以将字体类型和脚本设置为支持 unicode 的字体类型和脚本。

您可能还希望查看一些用于操作 unicode 字符串的内置函数,例如“StrConv”、“ChrW$”等。

于 2012-05-09T03:36:24.073 回答
0

我相信您的问题与我们在大多数可用控件中遇到的 VB6 源代码字符串文字中的相同 ANSI 问题有关。

您的:

CreateRecordset.Open "Exec sp_Insert_item 1, 101, N'Ħass'", conn, adOpenForwardOnly

实际上是:

CreateRecordset.Open "Exec sp_Insert_item 1, 101, N'Hass'", conn, adOpenForwardOnly

...在您将其粘贴到那里之后。

这是一种足够常见的事情,我经常使用我调用的类EscerLite来帮助处理这个问题。当然,它在运行时运行,很遗憾,但它通常优于在代码中的字符串文字中连接 ChrW$() 调用的替代方法。

我通常编辑 .CLS 文件,以便生成Attribute VB_PredeclaredId = True一个全局的、预先声明的实例(就像 VB6 .FRM 模块所做的那样,这是以模块名称命名的“自由”Form 实例的来源)。但你当然不必这样做。

它定义了一个方法:UnEscape而我的完整版本Escer也有一个Escape“其他方式”的方法 - 对于设置的序列化等很有用。

这使您可以编写:

CreateRecordset.Open EscerLite.UnEscape("Exec sp_Insert_item 1, 101, N'^u0126ass'"), _
                     conn, _
                     adOpenForwardOnly

但是您可以制定自己的方案,或者只使用 ChrW$() 调用。

EscerLite.cls

Option Explicit

Private Enum UnEscStates
    uesNotInEscapeSeq = 0
    uesProcessingEscSeq = 1
    uesProcessingLongEscSeq = 2
    uesProcessingLongEscSeqXEnd = 3
    uesProcessingLongEscSeqUEnd = 5
End Enum

Public Function UnEscape(ByVal EscapedText As String) As String
    'Un-escape a string value.  Escape sequences supported:
    '
    '   ^xhh   7 bit hex               ^r     vbCr
    '   ^uhhhh 16 bit hex ("Unicode")  ^l     vbLf
    '   ^b     vbBack                  ^n     vbNewLine/vbCrLf
    '   ^t     vbTab                   ^q     quote (")
    '   ^v     vbVerticalTab           ^0     vbNullChar
    '   ^f     vbFormFeed              ^^     ^

    Dim Pos As Long
    Dim ChS As String
    Dim ChW As Integer
    Dim UpChW As Integer
    Dim UnEscState As UnEscStates
    Dim UnPos As Long
    Dim Unicode As Boolean
    Dim Accum As Long

    UnEscape = Space$(Len(EscapedText))
    UnPos = 1&
    For Pos = 1& To Len(EscapedText)
        ChS = Mid$(EscapedText, Pos, 1&)
        ChW = AscW(ChS)
        UpChW = AscW(UCase$(ChS))
        Select Case UnEscState
            Case uesNotInEscapeSeq
                If ChW = 94# Then ' "^"
                    UnEscState = uesProcessingEscSeq
                End If
            Case uesProcessingEscSeq
                UnEscState = uesNotInEscapeSeq
                Select Case UpChW
                    Case 88# ' "X"
                        UnEscState = uesProcessingLongEscSeq
                    Case 85# ' "U"
                        Unicode = True
                        UnEscState = uesProcessingLongEscSeq
                    Case 66# ' "B"
                        ChS = vbBack
                    Case 84# ' "T"
                        ChS = vbTab
                    Case 86# ' "V"
                        ChS = vbVerticalTab
                    Case 70# ' "F"
                        ChS = vbFormFeed
                    Case 82# ' "R"
                        ChS = vbCr
                    Case 76# ' "L"
                        ChS = vbLf
                    Case 78# ' "N"
                        Mid$(UnEscape, UnPos, 1&) = vbCr
                        UnPos = UnPos + 1
                        ChS = vbLf
                    Case 81# ' "Q"
                        ChS = """"
                    Case 48# ' "0"
                        ChS = vbNullChar
                    Case 94# ' "^", i.e. ^^
                        '
                    Case Else
                        Err.Raise 5
                End Select
            Case Else
                If (48# <= UpChW And UpChW <= 57#) Then
                    Accum = 16& * Accum + (CLng(UpChW) And &HF&)
                ElseIf (65# <= UpChW And UpChW <= 70#) Then
                    Accum = 16& * Accum + (CLng(UpChW) - 55&)
                Else
                    Err.Raise 5
                End If
                UnEscState = UnEscState + 1&
                If Unicode Then
                    If UnEscState > uesProcessingLongEscSeqUEnd Then
                        ChS = ChrW$(Accum)
                        Accum = 0&
                        UnEscState = uesNotInEscapeSeq
                        Unicode = False
                    End If
                Else
                    If Accum > 127 Then Err.Raise 5
                    If UnEscState > uesProcessingLongEscSeqXEnd Then
                        ChS = ChrW$(Accum)
                        Accum = 0&
                        UnEscState = uesNotInEscapeSeq
                    End If
                End If
        End Select
        If UnEscState = uesNotInEscapeSeq Then
            Mid$(UnEscape, UnPos, 1&) = ChS
            UnPos = UnPos + 1&
        End If
    Next
    If UnEscState <> uesNotInEscapeSeq Then Err.Raise 5
    UnEscape = Left$(UnEscape, UnPos - 1&)
End Function
于 2012-05-09T19:40:52.577 回答