SQL Server — MSSQL + Ошибка вставки восточного символа

У меня проблема с вставкой восточного символа с переменными связывания в 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.

Кто-нибудь знает, как это работает? какой-то кастинг или что?

Спасибо!

1

Решение

Решение, которое использует только 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;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]