BOOLEAN Werte sind nicht für jedermann intuitiv. Hier ist ein netter Trick, um 0 und 1 etwas verständlicher zu machen.
In PHP existiert eine Funktion natsort, die ein Array von Argumenten derart sortiert, wie es auch ein Mensch machen würde. Also, angenommen man hat folgendes Array
DECLARE @codesnippet varchar(100);
SET @codesnippet = 'EnterStringHere';
SELECT
O.type_desc AS ObjectType,
(LEFT(OBJECT_NAME(M.[object_id]), 50)) AS ObjectName
FROM
sys.sql_modules M
JOIN
sys.objects O ON M.[object_id] = O.[object_id]
WHERE
definition LIKE '%' + @codesnippet + '%'
AND
OBJECTPROPERTY(M.[object_id], 'IsMSShipped') = 0
ORDER BY
ObjectName;
In diesem Beitrag haben wir uns mit der Rückgabe von Werten einer Spalte als separierte Liste beschäftigt. Vielfach sieht man aber auch die Anforderung, diese Liste auf der Basis eines bestimmten Schlüsselwertes zu generieren.
Die Konvertierung von FLOAT Daten in CHAR oder VARCHAR im SQL Server 2000 kann unter Umständen für Überraschungen sorgen, die mehr oder weniger unangenehm sind. Mal angenommen wir finden einen gültigen Grund, warum wir FLOAT in VARCHAR umwandeln wollen und haben folgende Basisdaten
CREATE TABLE t1
(
Preis FLOAT
)
INSERT INTO t1 SELECT 0.99
UNION ALL SELECT 9.99
UNION ALL SELECT 99.99
UNION ALL SELECT 999.99
UNION ALL SELECT 9999.99
Die Abfrage, die diese Daten umwandeln soll, sieht folgendermaßen aus:
SELECT
CAST(Preis AS VARCHAR(10)) Preis
FROM t1
Preis
----------
0.99
9.99
99.99
999.99
9999.99
(5 row(s) affected)
So, kein Problem bisher. Nun betrachten wir einmal folgende Basisdaten:
INSERT INTO t1 SELECT 10000
UNION ALL SELECT 10000.49
UNION ALL SELECT 10000.5
UNION ALL SELECT 10000.51
UNION ALL SELECT 10000.99
SELECT
CAST(Preis AS VARCHAR(10)) Preis
FROM t1
Preis
----------
10000
10000.5
10000.5
10000.5
10001
(5 row(s) affected)
Es sieht ganz danach aus, als ob SQL Server 2000 ab 10000 intern eine Rundung vornimmt. Etwas in der Form.
SELECT
CAST(Preis AS VARCHAR(10)) Preis
, CONVERT(VARCHAR, Preis,0) FROM t1 Preis ---------- ------------------------------ 10000 10000 10000.5 10000.5 10000.5 10000.5 10000.5 10000.5 10001 10001 (5 row(s) affected)
So, wie kriegt man es nun hin, daß auch die Daten heraus kommen, die eingegeben wurden?
Eine Möglichkeit besteht darin, die Daten erst explizit in DECIMAL umzuwandeln und anschließend zurück in VARCHAR. Etwa so:
SELECT
CAST(Preis AS VARCHAR(10)) Preis
, CONVERT(VARCHAR, Preis,0)
, CAST(CAST(PREIS AS DECIMAL(8,2)) AS VARCHAR(20)) FROM t1 Preis ---------- ------------------------------ -------------------- 10000 10000 10000.00 10000.5 10000.5 10000.49 10000.5 10000.5 10000.50 10000.5 10000.5 10000.51 10001 10001 10000.99 (5 row(s) affected)
Eine weitere Möglichkeit wäre:
SELECT
CAST(Preis AS VARCHAR(10)) Preis
, CONVERT(VARCHAR, Preis,0)
, CAST(CAST(PREIS AS DECIMAL(8,2)) AS VARCHAR(20))
, LTRIM(RTRIM(STR(ROUND(Preis,2),10,2)))
FROM t1
Preis
---------- ------------------------------ -------------------- ----------
10000 10000 10000.00 10000.00
10000.5 10000.5 10000.49 10000.49
10000.5 10000.5 10000.50 10000.50
10000.5 10000.5 10000.51 10000.51
10001 10001 10000.99 10000.99
(5 row(s) affected)
Diese Methode geht nicht den Umweg über die explizite Konvertierung in einen anderen Datentypen. STR() wandelt FLOAT direkt um. Das RTRIM() ist zwar nicht zwingend notwendig, aber schadet auch nicht wirklich.
Warum zeigt SQL Server dieses Verhalten? Ehrlich gesagt, habe ich darauf keine Antwort. Eventuell könnte Single und Double Precision beim FLOAT Datentyp eine Rolle spielen, aber dies ist nur eine Vermutung. Falls jemand eine schlüssige Begründung für dieses Verhalten hat, würde ich micht freuen, diese zu hören.
Liest man sich die Onlinehilfe von SQL Server durch und gelangt an das Thema ISNUMERIC(), erhält man den Eindruck, daß dies eine einfache, schnelle und sichere Methode ist, um zu überprüfen, ob ein gegebener Ausdruck in einen von SQL Server unterstützten numerischen Datentypen umgewandelt werden kann. Also, in einen der Datentypen: INTEGER, FLOAT (REAL), DECIMAL (NUMERIC) und MONEY.
Das Problem hat wahrscheinlich jeder schon einmal gehabt. Man stellt Importanforderungen auf, und die Anwender kümmern sich nicht darum und liefern anstelle von sauber getrennten Strings und Zahlen einen bunten Mischmasch aus beidem.