J'ai des difficultés à déboguer manuellement une application .NET où les valeurs Guid diffèrent de .NET à Oracle.
17D89D326C2142D69B989F5201288DBF
329DD817216CD6429B989F5201288DBF
Comment pourrais-je déboguer manuellement, c'est-à-dire à partir de C # GUID pouvoir coller cette valeur dans une requête Oracle et obtenir les résultats corrects (et vice versa)?
Si vous regardez les valeurs impliquées (par paires) de chiffres hexadécimaux, vous pouvez voir que les 7 derniers octets sont les mêmes dans les deux cas, mais les 9 premiers sont inversés un peu.
En partant de votre exemple, mais en réécrivant chaque paire dans le .NET en 00, 11, 22, etc., et en changeant également l'octet d'Oracle, nous obtenons:
.NET:
00112233445566778899AABBCCDDEEFF
Oracle:
33221100554477668899AABBCCFFEEFF
Il devrait donc être assez facile d'écrire du code pour passer d'un octet à l'autre. (Je suis presque sûr d'avoir écrit du code pour le faire dans un travail précédent, en fait.)
Pour passer d'un octet à l'autre, il vous suffit d'appeler Guid.ToByteArray()
et new Guid(byte[])
pour revenir à un Guid
.
EDIT: En l'occurrence, le basculement ci-dessus est exactement ce que fait le constructeur Guid
lorsque vous lui passez un tableau d'octets:
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("-", ""));
}
}
Tirages:
00112233445566778899AABBCCDDEEFF
33221100554477668899aabbccddeeff
Cela pourrait bien simplifier considérablement la commutation ... comment avez-vous obtenu les valeurs pour commencer? Est-ce simplement "comment ils sont affichés dans Oracle"?
EDIT: D'accord, voici quelques fonctions de conversion - si vous avez les données sous forme de texte, elles seront converties 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;
}
}
Je viens d'avoir ce même problème lors du stockage et de la lecture des guides d'Oracle.
La réponse de Jon est correcte pour l'interrogation, mais si votre application doit stocker et lire des guides d'Oracle, utilisez la fonction FlipEndian de ce fil:
Byte[] rawBytesFromOracle;
Guid dotNetGuid = new Guid(rawBytesFromOracle).FlipEndian();
Le retournement n'est requis que lors de la relecture d'Oracle.
Lorsque vous écrivez dans Oracle, utilisez Guid.ToByteArray () comme d'habitude.
J'ai passé TROP de temps à essayer d'accomplir cette tâche simple.
Steve
Si vous devez convertir un GUID en BRUT 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;
Utilisez toujours votre GUID
standard dans .NET ...
Lorsque vous souhaitez insérer un GUID
dans Oracle, vous appelez simplement Guid.ToString ( "N")
et alimentez cette chaîne à Oracle (dans cet exemple, le nom du paramètre 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;
Lorsque 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);
Ensuite, vous pouvez alimenter le MyNETVal
retourné dans new Guid (MyNETVal)
.
De cette façon, votre code traite toujours le format .NET et la commutation d'octets se produit dans la base de données Oracle ... vous ne polluez pas votre code avec le code de conversion et pouvez conserver le même code lors du passage à d'autres bases de données - changez simplement le SQL et vous êtes opérationnel ... le SQL pourrait devenir plus simple avec d'autres bases de données car certaines d'entre elles suivent le format GUID de Windows ...