簡體   English   中英

Unicode轉換,數據庫困境(Delphi 2007到XE2)

[英]Unicode conversion, database woes (Delphi 2007 to XE2)

目前,我正在將所有Delphi 2007代碼庫更新為Delphi XE2。 最重要的考慮因素是ANSI到Unicode的轉換,我們通過將所有基類型(char / string)重新定義為ANSI類型(ansichar / ansistring)來處理。 這在我們的許多程序中都有效,直到我開始使用數據庫。

當我將存儲從文件讀取的信息的程序轉換為SQL Server 2008數據庫時,問題就出現了。 使用字符串定位數據的突然簡單查詢將失敗,例如:

SELECT id FROM table WHERE name = 'something'

name字段是varchar 我發現我能夠通過在字符串名稱前加上N成功完成查詢。 我的印象是varchar 只能存儲ANSI字符,但它似乎存儲了Unicode?

更多信息:Delphi中的name字段是string[13] ,但我嘗試刪除[13] 數據庫排序SQL_Latin1_General_CP1_CI_ASSQL_Latin1_General_CP1_CI_AS 我們使用ADO與數據庫連接。 連接信息存儲在ODBC管理器中。

注意:由於Panagiotis的一些指示,我已經解決了我的實際問題。 我們從地圖文件中讀取的名稱是array[1..24] of AnsiChararray[1..24] of AnsiChar 該值被隱式轉換為string[13] ,其中包含空字符。 因此,具有5個字符的名稱實際上被存儲為數據庫中的5個字符+8個空字符。

varchar字段不存儲Unicode字符。 它們將ASCII值存儲在字段排序規則指定的代碼頁中。 當您嘗試存儲來自不同代碼頁的Unicode或數據時,SQL Server將嘗試將字符轉換為正確的代碼頁。 您可以禁用此功能,但最好的選擇是通過在應用程序中使用nvarchar字段和UnicodeString來避免整個混亂。

您提到您將所有字符類型更改為ANSI,而不是應用程序中的UNICODE類型。 如果要使用UNICODE,則應使用UNICODE類型,如UnicodeString。 否則,在將值發送到服務器時,您的值將轉換為ANSI。 當您創建發送到服務器的AnsiString時,您的代碼將完成此轉換。

順便說一句,您的select語句在字段中存儲ASCII值。 如果要將值存儲為unicode值,則必須將值前置為N,例如.g

SELECT id FROM table WHERE name = N'something'

即使這樣也無法保證您的數據將以Unicode格式到達服務器。 如果將語句存儲在AnsiString中,則整個語句在發送到服務器之前將轉換為ANSI。 如果您的應用程序進行了錯誤的轉換,您最終會在服務器上出現損壞的數據。

解決方案非常簡單,只需使用參數化語句將unicode值作為unicode參數傳遞,並將它們存儲在NVarchar字段中。 它更快,避免所有轉換錯誤並防止SQL注入攻擊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM