Soru Oracle'ın RAW'sini (16) .NET'in GUID'sine dönüştürme


Guid değerlerinin .NET'ten Oracle'a farklılık gösterdiği bir .NET uygulamasını el ile hata ayıklamada zorluklar yaşıyorum.

  • C # nerede okur:
    • 17D89D326C2142D69B989F5201288DBF
  • Oracle okur:
    • 329DD817216CD6429B989F5201288DBF

El ile hata ayıklamayı nasıl yapabilirim, yani C # 'dan GUID' e oracle sorgusunda bu değeri yapıştırabilir ve doğru sonuçları (ve viceversa) alabilir miyim?


29
2017-09-02 22:18


Menşei


Olası kopya Bayt dizisini Oracle RAW'dan System.Guid'e dönüştürün? - Chris J
neden ipi kullanmıyordum? fml - Toolkit


Cevaplar:


Onaltılık basamakların içerdiği değerlere (çiftler halinde) bakarsanız, son 7 baytın her iki durumda da aynı olduğunu görebilirsiniz, ancak ilk 9 bir bitin etrafında değiştirilir.

Örneğinizden yola çıkarak, ancak .NET'deki her çifti 00, 11, 22 vb. Gibi yeniden yazarak Oracle'ın ilgili baytını değiştiriyoruz:

  • .AĞ:

    00112233445566778899AABBCCDDEEFF
    
  • Oracle:

    33221100554477668899AABBCCFFEEFF
    

Bu nedenle ilgili baytlar arasında geçiş yapmak için kod yazmak oldukça kolay olmalıdır. (Aslında, önceki bir işte bunu yapmak için bir kod yazmıştım, aslında.)

Baytları değiştirmek için sadece aramak isteyeceksiniz Guid.ToByteArray() ve new Guid(byte[]) a geri almak Guid.

DÜZENLEME: Olduğu gibi, yukarıdaki geçiş yuvarlak kesinlikle ne Guid yapıcı bir bayt dizisi ilettiğinizde yapar:

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("-", ""));
    }
}

Baskılar:

00112233445566778899AABBCCDDEEFF
33221100554477668899aabbccddeeff

Bu, anahtarlamayı gerçekleştirmek için çok daha kolay hale getirebilir ... Başlangıç ​​değerlerini nasıl ele geçirdiniz? Sadece "Oracle'da nasıl gösteriliyor"?

DÜZENLEME: Tamam, burada birkaç dönüşüm fonksiyonu var - verileri metin olarak aldınız, her şekilde dönüşecekler ...

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;
    }

}

42
2017-09-02 22:40



Bu, şeyleri yeniden sıralayan bir Oracle olmadığını ortaya koyuyor. Guid.ToByteArray () ve parametresi olarak bayt dizisini alan Guid kurucusu. Bunu neden yaptığına dair hiçbir fikrim yok ve tam olarak burada bir soru sordum: stackoverflow.com/questions/9195551/... - Cory McCarty


Oracle’dan Guids’i saklarken ve okurken aynı sorunu yaşadım.

Jon'un cevabı sorgulama için doğrudur, ancak uygulamanızın Oracle'dan Guids'i saklaması ve okuması gerekiyorsa, bu iş parçacığından FlipEndian işlevini kullanın:

.NET Yerel GUID dönüşümü

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

Kapak sadece Oracle'dan geri okurken gereklidir.

Oracle'a yazarken Guid.ToByteArray () öğesini normal olarak kullanın.

Bu basit görevi başarmaya çalışmak için çok zaman harcadım.

Steve


6
2017-10-06 14:15





Bir dönüştürmeniz gerekirse GUID için ÇİĞ itibaren PL / SQL Bu işlevi kullanabilirsiniz:

/*
    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;

4
2018-02-26 12:42





Sadece her zaman senin standardını kullan GUID net olarak...

Bazılarını eklemek istediğinizde GUID Oracle’a aramanız yeterli Guid.ToString ( "N") ve bu dizgeyi Oracle'a besle (bu örnekte param adı 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;

Okuduğun zaman RAW kullandığınız Oracle:

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);

Sonra geri döndürebilirsiniz MyNETVal içine new Guid (MyNETVal).

Bu şekilde kodunuz her zaman .NET formatıyla ilgilenir ve bayt anahtarlama Oracle-DB'de gerçekleşir ... kodunuzu dönüştürme koduyla yok etmezsiniz ve diğer DB'lere geçiş yaparken kod kodunu aynı tutabilirsiniz. SQL ve siz çalışıyorsunuz ve ... SQL'in diğer DB'lerle daha kolay olması bazılarının Windows GUID formatını takip etmesinden dolayı ...


1
2017-09-02 22:56



OP'nin sorduğu bu değil. Eğer .NET'in kimlikleri bertaraf edeceğini bilseydim, hemen VARCHAR2'yi tercih ederim. Ama şimdi çok geç, şimdi onları nasıl eşleştireceğimi anlamaya ihtiyacım var. - Toolkit