从VB6插入时未保存Unicode字符

时间:2012-05-08 18:14:10

标签: sql-server unicode vb6 character-encoding

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

Exec sp_Insert_item 1, 101, N'Ħass'

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

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

谢谢, 艾伦

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分: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

...将它粘贴到那里后。

这是一种常见的事情,我经常使用Class I调用EscerLite来帮助解决这个问题。当然,它在运行时运行,遗憾的是,它通常胜过在代码中我的String文字中连接ChrW $()调用的替代方法。

我通常编辑.CLS文件,以便Attribute VB_PredeclaredId = True导致一个全局的,预先声明的实例(就像VB6 .FRM模块一样,这是为模块名称命名的“free”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