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 値に変換します

注: これは、HEX での重の実際の意味ではありません

元の値に戻すことができる方法で保管してください。たとえば、0d3114af は 0d - 31 - 14 - af または 0d31 - 14af です。| のような区切り記号を使用できます。または。しかし、1 つの方法は、前に 00 のパディングを提供することです。英語の文字は 31 のように 2 文字の長さしかないか、英語以外の af は 14af のように 4 文字になります。これを知っていれば、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 に答える