web-dev-qa-db-ja.com

Oracle RAW(16)から.NETへの変換GUID

Guid値が.NETとOracleで異なる.NETアプリケーションを手動でデバッグするのが困難です。

  • C#の読み取り場所:
    • 17D89D326C2142D69B989F5201288DBF
  • Oracleの読み取り:
    • 329DD817216CD6429B989F5201288DBF

どのように手動でデバッグできますか?つまり、C#のGUID= Oracleクエリにその値を貼り付けて正しい結果を得ることができます(およびその逆)?

36
rebelliard

16進数の値を(ペアで)見ると、最後の7バイトはどちらの場合も同じですが、最初の9バイトは少しずつ入れ替わっていることがわかります。

あなたの例から移動しますが、.NETの各ペアを00、11、22などに書き換え、Oracleの関連バイトも切り替えます:

  • 。ネット:

    _00112233445566778899AABBCCDDEEFF
    _
  • Oracle:

    _33221100554477668899AABBCCFFEEFF
    _

そのため、関連するバイトを切り替えるためのコードを書くのはかなり簡単です。 (実際、前の仕事でこれを行うためのコードをいくつか書いたと確信しています。)

バイトを丸めるには、Guid.ToByteArray()new Guid(byte[])を呼び出してGuidに戻ります。

編集:たまたま、上記の切り替えはexactlyバイト配列を渡すときにGuidコンストラクターが行うことです:

_using System;
using System.Linq;

class Test
{
    static void Main()
    {
        byte[] bytes = Enumerable.Range(0, 16)
                                 .Select(x => x * 16 + x)
                                 .Select(x => (byte) x)
                                 .ToArray();

        Console.WriteLine(BitConverter.ToString(bytes).Replace("-", ""));
        Console.WriteLine(new Guid(bytes).ToString().Replace("-", ""));
    }
}
_

プリント:

_00112233445566778899AABBCCDDEEFF
33221100554477668899aabbccddeeff
_

それにより、切り替えを実行するのがかなり簡単になるかもしれません...最初に値をどのように把握しましたか? 「Oracleでの表示方法」だけですか?

編集:さて、ここにいくつかの変換関数があります-データをテキストとして取得している場合、それぞれの方法で変換します...

_using System;
using System.Linq;

class Test
{
    static void Main()
    {
        string Oracle = "329DD817216CD6429B989F5201288DBF";
        string dotNet = "17D89D326C2142D69B989F5201288DBF";

        Console.WriteLine(Oracle == DotNetToOracle(dotNet));
        Console.WriteLine(dotNet == OracleToDotNet(Oracle));
    }

    static string OracleToDotNet(string text)
    {
        byte[] bytes = ParseHex(text);
        Guid guid = new Guid(bytes);
        return guid.ToString("N").ToUpperInvariant();
    }

    static string DotNetToOracle(string text)
    {
        Guid guid = new Guid(text);
        return BitConverter.ToString(guid.ToByteArray()).Replace("-", "");
    }

    static byte[] ParseHex(string text)
    {
        // Not the most efficient code in the world, but
        // it works...
        byte[] ret = new byte[text.Length / 2];
        for (int i = 0; i < ret.Length; i++)
        {
            ret[i] = Convert.ToByte(text.Substring(i * 2, 2), 16);
        }
        return ret;
    }

}
_
49
Jon Skeet

OracleからGUIDを保存および読み取るときに、これと同じ問題が発生しました。

Jonの答えはクエリに対しては正しいですが、アプリでOracleからのGUIDを保存および読み取る必要がある場合は、このスレッドからFlipEndian関数を使用します。

。NET Native GUID conversion

Byte[] rawBytesFromOracle;
Guid dotNetGuid = new Guid(rawBytesFromOracle).FlipEndian();

フリップは、Oracleからの読み取り時にのみ必要です。

Oracleに書き込むときは、通常どおりGuid.ToByteArray()を使用します。

私はこの単純なタスクを達成するために多くの時間を費やしました。

スティーブ

7
samneric

[〜#〜] guid [〜#〜][〜#〜] raw [〜#〜]からPL/SQLはこの関数を使用できます:

/*
    CONVERT a GUID FORMAT in RAW(16)
    EX:
        guid    = 88c6a267-65d2-48d6-8da2-6f45e2c22726
        raw     = 67A2C688D265D6488DA26F45E2C22726
*/
FUNCTION GuidToRaw( guid IN VARCHAR2 ) RETURN RAW
IS
    ret         RAW(16);
    guidHex     VARCHAR2(64);
BEGIN

    guidHex := SUBSTR (guid, 7, 2);
    guidHex := CONCAT( guidHex, SUBSTR (guid, 5, 2) );
    guidHex := CONCAT( guidHex, SUBSTR (guid, 3, 2) );
    guidHex := CONCAT( guidHex, SUBSTR (guid, 1, 2) );

    guidHex := CONCAT( guidHex, SUBSTR (guid, 12, 2) );
    guidHex := CONCAT( guidHex, SUBSTR (guid, 10, 2) );

    guidHex := CONCAT( guidHex, SUBSTR (guid, 17, 2) );
    guidHex := CONCAT( guidHex, SUBSTR (guid, 15, 2) );

    guidHex := CONCAT( guidHex, SUBSTR (guid, 20, 2) );
    guidHex := CONCAT( guidHex, SUBSTR (guid, 22, 2) );

    guidHex := CONCAT( guidHex, SUBSTR (guid, 25, 12) );

    ret := HEXTORAW( guidHex );

    return ret;

end;
5
andreae75

.NETでは常に標準のGUIDを使用するだけです...

GUIDをOracleに挿入する場合は、Guid.ToString ( "N")を呼び出してその文字列をOracleに渡すだけです(この例では、パラメータ名はMyNETVALです)。

_INSERT INTO MyTable ( MyRAWCol)
SELECT HEXTORAW (SUBSTR (MyNETVal, 6, 2) || SUBSTR (MyNETVal, 4, 2) || SUBSTR (MyNETVal, 2, 2) || SUBSTR (MyNETVal, 0, 2) || SUBSTR (MyNETVal, 10, 2) || SUBSTR (MyNETVal, 8, 2) || SUBSTR (MyNETVal, 14, 2) || SUBSTR (MyNETVal, 12, 2) || SUBSTR (MyNETVal, 16, 16)) FROM DUAL;
_

OracleからRAWを読み取るときは、次を使用します。

_SELECT 
SUBSTR (HexV, 6, 2) || SUBSTR (HexV, 4, 2) || SUBSTR (HexV, 2, 2) || SUBSTR (HexV, 0, 2) || SUBSTR (HexV, 10, 2) || SUBSTR (HexV, 8, 2) || SUBSTR (HexV, 14, 2) || SUBSTR (HexV, 12, 2) || SUBSTR (HexV, 16, 16) AS MyNETVal
FROM (SELECT RAWTOHEX (MyRAWCol) HexV FROM MyTable);
_

次に、返されたMyNETValnew Guid (MyNETVal)にフィードできます。

このように、コードは常に.NET形式を処理し、バイトスイッチングはOracle-DBで行われます...変換コードでコードを汚染せず、他のDBに切り替えるときにコードコードを同じに保つことができます-変更するだけですSQLとあなたが稼働しています...他のDBではSQLがよりシンプルになる可能性があります。なぜなら、それらのいくつかはWindowsのGUID形式...

1
Yahia