在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时。
有人知道怎么做吗?选角什么的?
谢谢!
只使用PHP(甚至JavaScript)的解决方案是将字符转换为HEX值并存储。我不知道你是否想走这条路,但我没有时间向你展示代码,但这是完整的理论:
检测到非英文字符,如下所示:重
转换为HEX值(先看这里。但搜索Javascript将帮助您找到更好的方法,即使在PHP中也是如此):14af
注:事实并非如此重真的是在HEX
以可以转换回其原始值的方式存储。例如,你如何判断这是什么:0d3114af是0d-31-14-af还是0d31-14af。你可以使用像|或a这样的分母。但一种方法是在前面提供00的填充。一个英文字符将只有2个字符长,如31,或者非英文字符将是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;
}