2

私は、PC のインベントリ作成に OCS Inventory を使用しています。ほぼ問題なく動作しますが、これらの PC の 99% は Windows(R): XP および Seven で動作します。また、WMI 情報には標準がありません。

たとえば、OCS エージェント (データを収集して OCS サーバーに送信するターゲット PC 上の常駐プログラム) は、" Realtek PCIe GBE Family Controller (1 Gb/s) " (純粋な英語、エンコーディングは問題ではありません) として応答を受け取る場合があります。または " ¨£ ¡¨â®¥ á¥â¥¢®¥ ¯®¤ª«î票¥ Intel(R) 82566DM-2 (100 Mb/s) " (正しくない、ロシア語、CP1251)、または" Realtek RTL8169/8110 Family Gigabit Ethernet NIC - Ìèíèïîðò ïëàíèðîâùèêà ïàêåòîâ (100 Mb/s) " (ロシア語、CP866 が正しくありません)。または " VIA Rhine III Fast Ethernet Adapter - Минипорт планировщика пакетов (100 Mb/s) " (正しい、ロシア語、UTF8、または別の Unicode)

Windows がこれらの結果を 1 つのエンコーディングだけで返すようにする方法はありません。ドライバの .INF ファイルでどのエンコーディングが使用されたか、WMI によってエンコーディングが返されるかどうかは、ドライバ メーカーの考えに任されているようです。

ほとんどの問題ではありませんが、上司は、IT インフラストラクチャの状態に関する四半期報告書に「象形文字」が表示されるのを非常に嫌います。そして、彼らは正しいようです。

オンザフライで、あるエンコーディングから別のエンコーディングに単一フィールドを再エンコードする方法はありますか? 内容が混在しているため、列全体を再エンコードしません。どのエンコードが使用されたかは大まかに判断できますが、 MySQL の SQL 言語のみを使用して再エンコードして正しいレポートを作成する方法がわかりません。

実用的な提案はありますか?

4

1 に答える 1

0

唯一の方法は、ストアド プロシージャを記述することだったようです。やった。左の列(castbin)は処理前のテキスト、右の列( )は処理converted後の同じテキスト

ここに画像の説明を入力

コードを見てみましょう

...
#above and below are regular MySQL statements
@castbin:=cast(networks.description as char character set binary) as castbin,
@convv:=convert(repcxaxex(@castbin) using cp866) as converted
...

@castbin明確化と読みやすさのためにのみ使用される変数。repCxAxEx「0xCx 0xAx を 0xCx 0xEx に置き換える」という名前の関数によって実行されるすべてのジョブ。これは、この関数の非常に最適ではないが機能するコードです (MySQL Studio から取得)。

See corrected text of the function below in update section

最初に文字列が変換可能かどうかを確認し、次に for と prefix の 2 つの変換を行い0xC2ます0xC3。これらのプレフィックスは異なるエンコーディング エラーを意味するためです。

更新: 徹底的なテストにより、いくつかの間違いが見つかりました。

クエリ内のどこかで、group_concat演算子を使用して、同じ PC の複数のプロパティの値を、区切り文字として "\n" を使用した 1 つの長い文字列にマージします。そのような場合、変換が機能しないことがあります。

-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER=`root`@`%` FUNCTION `repcxaxex`(s2c text charset binary) RETURNS blob
begin
/*исправляем проблемы с кодировками*/
    set @i:=0;
    set @s:=s2c;
    set @altered:='0';
    if ((left(@s,1)=char(0xc2)) or instr(@s,char(32,0xc2)) or instr(@s,char(0x0a,0xc2))) then
    while @i<16 do
        set @s:=replace(@s,char(0xc3,(160+@i)),char(0xd3,(224+@i)));
        set @i:=@i+1;
    end while;
    set @i:=1;
    while @i<4 do
        set @s:=replace(@s,char(0xc0+@i),'');
        set @s:=replace(@s,char(0xd0+@i),'');
        set @i:=@i+1;
    end while;
    set @altered:='1';
    end if;
    set @i:=0;
    if ((left(@s,1)=char(0xc3)) or instr(@s,char(32,0xc3)) or instr(@s,char(0x0a,0xc3))) then
    while @i<16 do
        set @s:=replace(@s,char(0xc3,(176+@i)),char(0xd3,(224+@i)));
        set @i:=@i+1;
    end while;
    set @i:=1;
    while @i<4 do
        set @s:=replace(@s,char(0xc0+@i),'');
        set @s:=replace(@s,char(0xd0+@i),'');
        set @i:=@i+1;
    end while;
    set @altered:='2';
    end if;
/*Добавляем 0 или 1 в начало строки, чтобы показать, конвертировали ее или нет
выводить надо будет, начиная со второго символа*/
    set @s=concat(@altered,@s);
    return @s;
end

終了時に、関数は返された文字列の先頭に 1 桁を追加します。数字自体は@altered変数によって決定され、そのコードは一目瞭然です。

呼び出しのより正しい形式は次のとおりです。

If (left(repcxaxex(string-to-convert),1)='0',string-to-convert,mid(convert(repcxaxex(string-to-convert) using cp866),2))
于 2015-12-29T01:48:05.143 に答える