У меня проблема с вставкой восточного символа с переменными связывания в 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 и его сохранении. Я не знаю, хотите ли вы пойти по этому пути, но у меня нет времени, чтобы показать вам код, но вот полная теория:
Обнаружен не английский язык, например: 重
Преобразовать в шестнадцатеричное значение (Посмотрите здесь для начала. Но поиск по Javascript поможет вам найти лучшие способы сделать это даже в PHP): 14af
ПРИМЕЧАНИЕ: это не то, что на самом деле есть в HEX
Хранить таким образом, чтобы вы могли преобразовать обратно в исходное значение. Например, как вы можете сказать, что это такое: 0d3114af это 0d — 31 — 14 — af или 0d31 — 14af. Вы можете использовать разделители, как | или но один из способов заключается в том, чтобы обеспечить заполнение 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;
}
Других решений пока нет …