Conversion de RAW D'Oracle (16) to.NET ' s Guide

j'ai des difficultés à déboguer manuellement une application .NET où les valeurs Guid diffèrent de .NET à Oracle.

  • où C # lit:
    • 17D89D326C2142D69B989F5201288DBF
  • Oracle lit:

    • 329DD817216CD6429B989F5201288DBF

Comment pourrais-je déboguer manuellement, c'est-à-dire à partir du gui de C# coller cette valeur dans une requête oracle et obtenir les bons résultats (et vice versa)?

29
demandé sur rebelliard 2011-09-03 02:18:22
la source

4 ответов

si vous regardez les valeurs impliquées (en paires) des chiffres hexadécimaux, vous pouvez voir que les 7 derniers octets sont les mêmes dans les deux cas, mais les 9 premiers sont intervertis un peu.

à partir de votre exemple, mais réécrire chaque paire dans le .NET comme 00, 11, 22 etc et commuter le byte pertinent D'Oracle ainsi nous obtenons:

  • .NET:

    00112233445566778899AABBCCDDEEFF
    
  • Oracle:

    33221100554477668899AABBCCFFEEFF
    

de sorte qu'il devrait être assez facile d'écrire du code pour changer autour des octets pertinents. (Je suis assez sûr que j'ai écrit un code pour faire cela dans un travail précédent, en fait.)

pour changer les octets, vous n'avez qu'à appeler Guid.ToByteArray() et new Guid(byte[]) pour revenir à un Guid .

EDIT: Comme il arrive, l'interrupteur de la tour ci-dessus est exactement ce que le Guid le constructeur fait quand vous lui passez un tableau de byte:

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

Imprime:

00112233445566778899AABBCCDDEEFF
33221100554477668899aabbccddeeff

qui pourrait bien simplifier considérablement l'exécution de la commutation... comment avez-vous obtenu les valeurs pour commencer? Est-ce juste "comment ils sont affichés dans Oracle"?

EDIT: ok, voici quelques fonctions de conversion - si vous avez les données en texte, ils convertiront dans chaque sens...

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
répondu Jon Skeet 2011-09-03 02:52:16
la source

je viens d'avoir ce même problème lors du stockage et de la lecture Guids D'Oracle.

la réponse de Jon est correcte pour la recherche, mais si votre application a besoin de stocker et de lire des Guids D'Oracle, utilisez la fonction FlipEndian à partir de ce fil:

.NET Native GUID conversion

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

le flip n'est nécessaire qu'à la lecture D'Oracle.

lors de l'utilisation D'Oracle GUID.ToByteArray() comme d'habitude.

j'ai passé trop de temps à essayer d'accomplir cette simple tâche.

Steve

7
répondu samneric 2017-05-23 15:25:55
la source

si vous avez besoin de convertir un GUID en RAW de PL / SQL peut utiliser cette fonction:

/*
    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
répondu andreae75 2014-02-26 16:42:48
la source

utilisez toujours votre standard GUID dans .NET ...

quand vous voulez insérer un peu de GUID dans Oracle vous appelez juste Guid.ToString ( "N") et donnez cette chaîne de caractères à Oracle (dans cet exemple le nom param est 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;

quand vous lisez un RAW D'Oracle vous utilisez:

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

puis vous pouvez alimenter le MyNETVal retourné dans new Guid (MyNETVal) .

de cette façon votre code traite toujours le format .NET et la commutation byte se produit dans L'Oracle-DB... vous ne polutez pas votre code avec le code de conversion et pouvez garder le code de code le même quand switchig à d'autres DBs - il suffit de changer le SQL et vous êtes en place et en cours d'exécution... le SQL pourrait devenir plus simple avec d'autres DBs parce que certains d'entre eux suivent le format GUID de Windows...

1
répondu Yahia 2011-09-03 03:08:34
la source

Autres questions sur