1

我在 SQL Server 中插入带有绑定变量的东方字符时遇到问题。我正在使用 MSSQL 命令和 PHP。

我的 PHP 代码是这样的:

$sql = "
    CREATE TABLE table_test
      (  id                int
        ,nvarchar_latin    nvarchar(255) collate sql_latin1_general_cp1_ci_as 
      );";

    $stmt = mssql_query($sql);

    $conn = mssql_connect("server","user","pass");
    mssql_select_db('test')

    $stmt = mssql_init('test..sp_chinese', $conn); 

    $id      = 1;      
    $nvarchar_latin  = '重建議';

    mssql_bind($stmt, '@id'          , $id            , SQLINT1);  
    mssql_bind($stmt, @nvarchar_latin, $nvarchar_latin, SQLVARCHAR); 

    mssql_execute($stmt);

我的程序是这样的:

ALTER PROCEDURE sp_chinese
  @id               int
 ,@nvarchar_latin   nvarchar (255) 
AS 
 BEGIN
 INSERT INTO char_chines (id, nvarchar_latin) 
      VALUES (@id, @nvarchar_latin);
 END

如果我将东方字符更改为正常字符,则此工作。如果我直接运行这个插入,它工作正常:

INSERT INTO table_test (id, nvarchar_latin) 
     VALUES (1, '重建議');

所以,很明显问题出在我将变量从 PHP 发送到 SQL Server 时。

任何人都知道如何使这个工作?一些铸造什么的?

谢谢!

4

1 回答 1

1

仅使用 PHP(甚至 JavaScript)的解决方案是将字符转换为其 HEX 值并存储它。我不知道你是否想走这条路,但我没有时间向你展示代码,但这里是完整的理论:

检测到非英文字符,如下所示:重</p>

转换为 HEX 值(在此处查找初学者。但搜索 Javascript 将帮助您找到更好的方法,即使在 PHP 中也是如此):14af

注意:这不是 HEX 中真正的重

以可以转换回其原始值的方式存储。例如,你怎么知道这是什么:0d3114af 是 0d - 31 - 14 - af 还是 0d31 - 14af。您可以使用分隔符,例如 | 或一个。但一种方法是在前面提供 00 的填充。一个英文字符只有 2 个字符长,如 31 或 af 非英语将是 4 个,如 14af。知道这一点后,您可以将每 4 个字符拆分并转换为它们的值。

缺点是您需要更改数据库以适应这些更改。

[ 更新 ] - - -

这里有一些 JavaScript 代码可以让你朝着正确的方向前进。这完全可以在 PHP 中复制。不过,这不会搜索字符,它是加密程序的一部分,所以它所关心的只是将所有内容都转换为 HEX。英文字符将用 00 填充(这是我自己的代码,因此没有指向源的链接):

function toHex(data) {
   var result = '';
   // Loop through entire string of data character by character
   for(var i=0;i<data.length;i++) {
     // Convert UTF-16 Character to HEX, if it is a 2 chracter HEX add 00 padding in front
     result += (data.charCodeAt(i) + 0x10000).toString(16).slice(1);
   }
   // Display the result for testing purposes
   document.getElementById('two').value = result;
}

function fromHex(data) {
   var result = '', block = '', pattern = /(00)/;  // Pattern is the padding
   for(var i=0;i<data.length;i = i+4) {
      // Split into separate HEX blocks
      block = data.substring(i,i+4);
      // Remove 00 from a HEX block that was only 2 characters long
      if(pattern.test(block)){
         block = block.substring(2,4);
      }
      // HEX to UTF-16 Character
      result += String.fromCharCode(parseInt(block,16));
   }
   // Display the result for testing purposes
   document.getElementById('two').value = result;
}
于 2014-09-24T22:21:23.263 回答