Sie sind eigentlich äquivalent, aber sie sind unabhängige Typen und keine technischen Synonyme, wie ROWVERSION
und TIMESTAMP
- obwohl sie in der Dokumentation möglicherweise zu einem Zeitpunkt als Synonyme bezeichnet wurden . Das ist eine etwas andere Bedeutung von Synonym (z. B. sind sie nicht unterscheidbar, außer im Namen, nicht einer ist ein Alias für den anderen). Ironisch, richtig?
Was ich aus dem Wortlaut in MSDN interpretiere, ist tatsächlich:
Diese Typen sind identisch, sie haben nur unterschiedliche Namen.
Abgesehen von den type_id
Werten ist hier alles identisch:
SELECT * FROM sys.types WHERE name IN (N'numeric', N'decimal');
Ich habe absolut keine Kenntnis von irgendwelchen Verhaltensunterschieden zwischen den beiden und gehe zurück auf SQL Server 6.5, habe sie immer als 100% austauschbar behandelt.
für DECIMAL (18,2) und NUMERIC (18,2)? Eine Zuordnung zu einer anderen ist technisch eine "Umstellung"?
Nur wenn Sie dies ausdrücklich tun. Sie können dies auf einfache Weise beweisen, indem Sie eine Tabelle erstellen und dann den Abfrageplan auf Abfragen untersuchen, die explizite oder - wie Sie vielleicht erwarten - implizite Konvertierungen ausführen. Hier ist eine einfache Tabelle:
CREATE TABLE [dbo].[NumDec]
(
[num] [numeric](18, 0) NULL,
[dec] [decimal](18, 0) NULL
);
Führen Sie nun diese Abfragen aus und erfassen Sie den Plan:
DECLARE @num NUMERIC(18,0);
DECLARE @dec DECIMAL(18,0);
SELECT
CONVERT(DECIMAL(18,0), [num]), -- conversion
CONVERT(NUMERIC(18,0), [dec]) -- conversion
FROM dbo.NumDec
UNION ALL SELECT [num],[dec]
FROM dbo.NumDec WHERE [num] = @dec -- no conversion
UNION ALL SELECT [num],[dec]
FROM dbo.NumDec WHERE [dec] = @num; -- no conversion
Wie im SQL Sentry Plan Explorer * gezeigt, ist der Plan nicht wirklich interessant:
Aber die Registerkarte Ausdrücke ist sicher:
Wie ich oben ausgeführt habe, haben wir explizite Conversions, bei denen wir darum gebeten haben, aber keine expliziten Conversions, bei denen wir sie erwartet hätten. Scheint, dass der Optimierer sie auch als austauschbar behandelt.
Probieren Sie auch diesen Test aus (Daten und Indizes).
CREATE TABLE [dbo].[NumDec2]
(
[num] [numeric](18, 2) NULL,
[dec] [decimal](18, 2) NULL
);
INSERT dbo.NumDec2([num],[dec])
SELECT [object_id] + 0.12, [object_id] + 0.12
FROM sys.all_columns;
CREATE INDEX [ix_num] ON dbo.NumDec2([num]);
CREATE INDEX [ix_dec] ON dbo.NumDec2([dec]);
Führen Sie nun diese Abfrage aus:
DECLARE @num NUMERIC(18,2) = -1291334356.88,
@dec NUMERIC(18,2) = -1291334356.88;
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = @num
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = @dec;
Plan hat keine Conversions (die Registerkarte "Ausdrücke" ist leer):
Auch diese führen zu keinen unerwarteten Konvertierungen. Natürlich sehen Sie es auf der rechten Seite im Prädikat, aber in keinem Fall musste eine Konvertierung für die Spaltendaten durchgeführt werden, um die Suche zu erleichtern (viel weniger erzwingen Sie einen Scan).
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(DECIMAL(18,2), @num)
UNION ALL
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(DECIMAL(18,2), @dec)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(NUMERIC(18,2), @num)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(NUMERIC(18,2), @dec)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(DECIMAL(18,2), @num)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(DECIMAL(18,2), @dec)
UNION ALL
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(NUMERIC(18,2), @num)
UNION ALL
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(NUMERIC(18,2), @dec);
Ich persönlich bevorzuge es, den Begriff DECIMAL
nur zu verwenden, weil er viel genauer und aussagekräftiger ist. BIT
ist auch "numerisch".
* Disclaimer: I work for SQL Sentry.