Folgendes berücksichtigen:
declare @dt datetime, @dt2 datetime2, @d date
set @dt = '2013-01-01'
set @dt2 = '2013-01-01'
set @d = '2013-01-01'
select convert(varbinary, @dt) as dt,
convert(varbinary, @dt2) as dt2,
convert(varbinary, @d) as d
Ausgabe:
dt dt2 d
------------------ -------------------- --------
0x0000A13900000000 0x07000000000094360B 0x94360B
Jetzt verstehe ich bereits aus der Dokumentation , datetime
die einen kleineren Bereich hat und vom 1753-01-01 beginnt, während datetime2
und date
0001-01-01 als Startdatum verwendet.
Was ich jedoch nicht verstehe, ist, dass datetime
es währenddessen Little-Endian zu sein scheint datetime2
und date
Big-Endian ist. Wenn dies der Fall ist, wie können sie dann überhaupt richtig sortiert werden?
Überlegen Sie, ob ich wissen möchte, wie viele ganzzahlige Tage ein date
Typ darstellt. Sie würden denken, Sie könnten dies tun:
declare @d date
set @d = '0001-01-31'
select cast(convert(varbinary, @d) as int)
Aber aufgrund der Endianness erhalten Sie 1966080 Tage!
Um das richtige Ergebnis von 30 Tagen zu erhalten, müssen Sie es umkehren:
select cast(convert(varbinary,reverse(convert(varbinary, @d))) as int)
Oder natürlich können Sie dies tun:
select datediff(d,'0001-01-01', @d)
Aber das bedeutet intern irgendwo, dass es die Bytes sowieso umkehrt.
Warum haben sie die Endianness gewechselt?
Es ist mir nur wichtig, weil ich an einem benutzerdefinierten UDT in SQLCLR arbeite und die binäre Reihenfolge der Bytes dort eine Rolle zu spielen scheint, aber diese integrierten Typen scheinen viel flexibler zu sein. Verfügt SQL Server über etwas Internes, bei dem jeder Typ seinen eigenen Sortieralgorithmus bereitstellen kann? Und wenn ja, gibt es eine Möglichkeit, diese für meine benutzerdefinierte UDT zu nutzen?
Siehe auch eine verwandte (aber andere) Frage zu StackOverflow.
quelle
IComparable
? Sie sollten sich niemals mit der internen Darstellung der Datentypen befassen müssen.IComparable
, aber es ist nur die clientseitige verwendet. SQL Server ignoriert dies und verlässt die Bytereihenfolge.Antworten:
SQL Server verlässt sich bei seinen "eigenen" Datentypen nicht auf die binäre Reihenfolge. Für CLR-Datentypen können Sie die iComparable-Schnittstelle verwenden, aber wie @MattJohnson erwähnt, ignoriert SQL Server dies:
http://connect.microsoft.com/SQLServer/feedback/details/252230/sqlclr-provide-the-ability-to-use-icomparable-or-a-similar-mechanism-for-udts
Microsoft veröffentlicht keine Details darüber, wie die verschiedenen Datentypen gespeichert und verarbeitet werden. In Books Online wird jedoch ausdrücklich darauf hingewiesen, dass Sie sich für einen bestimmten Datentyp nicht auf ein bestimmtes Binärformat verlassen können und dass sich das verwendete Format jederzeit ändern kann. Es ist daher eine gute Idee, ein INT als genau das und nicht als VARBINARY zu speichern, da Sie Ihre Daten nach dem nächsten SP möglicherweise nicht mehr lesen können.
Was die Sortierung betrifft: Der größte Teil des SQL Server-Kerns ist in C ++ geschrieben. Ich gehe davon aus, dass intern eine Methode ähnlich einer iComparable verwendet wird. Aber auch hier gibt es keine öffentlich zugängliche Dokumentation dazu. Selbst wenn dies der Fall wäre, könnten Sie es wahrscheinlich aufgrund der inhärenten Unterschiede zwischen .NET und C ++ nicht ausnutzen.
quelle
int
als Hintergrundfeld für meine CLR-UDT zu verwenden? Haben Sie ein Beispiel dafür? DieCREATE TYPE
Anweisung benötigt einebase_type
oder eine externe Assembly - aber nicht beide.