我有一个 VB6 应用程序,当尝试保存 unicode 字符时,这些字符没有正确保存在 Ms SQL 数据库中。直接在 SSMS 中执行插入语句时,插入正确执行。
Exec sp_Insert_item 1, 101, N'Ħass'
我在连接字符串中使用 SQLOLEDB 作为驱动程序,并且我的列设置为 NVarchar
有谁知道如何解决这个问题?
谢谢,艾伦
我有一个 VB6 应用程序,当尝试保存 unicode 字符时,这些字符没有正确保存在 Ms SQL 数据库中。直接在 SSMS 中执行插入语句时,插入正确执行。
Exec sp_Insert_item 1, 101, N'Ħass'
我在连接字符串中使用 SQLOLEDB 作为驱动程序,并且我的列设置为 NVarchar
有谁知道如何解决这个问题?
谢谢,艾伦
您是正确的,VB6 将支持 unicode。事实上,VB6 字符串本质上是 unicode,但问题是当从不正确支持它的用户控件显示/检索时,它会在翻译中丢失。
如果您从 UI 获取字符串,请确保使用支持它的文本框控件。例如,添加对 Microsoft Forms 2.0 对象库的引用,并在开箱即用的常规文本框控件上使用这些控件。这样,您可以将字体类型和脚本设置为支持 unicode 的字体类型和脚本。
您可能还希望查看一些用于操作 unicode 字符串的内置函数,例如“StrConv”、“ChrW$”等。
我相信您的问题与我们在大多数可用控件中遇到的 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