2014-09-24 43 views
1

我遇到了在SQL Server中插入具有绑定变量的东方字符的问题。 我正在使用MSSQL命令和PHP。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。

任何人都有线索如何使这个作品?一些铸造什么的?

谢谢!

回答

1

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

检测到非英文字符,如下所示:重

转换为十六进制值(Look here for starters.但Javascript的搜索将帮助您找到更好的方法来做到这一点,即使在PHP):14af

注意:这不是什么重真的是十六进制

存放在可以将其转换回原始值。例如,你怎么知道这是什么:0d3114af是0d - 31 - 14 - af是0d31 - 14af。您可以使用类似于|的分隔符或者a。但一种方法是在前面提供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; 
}