Discussion:
Umwandlung Hex->Dezimal
(zu alt für eine Antwort)
Sven Dörge
2005-08-12 08:55:03 UTC
Permalink
Hallo zusammen,

habe ein Brett vorm Kopf!!!!


declare @hex varbinary (4)
declare @dez numeric
declare @int int

set @hex=0x0000000A
set @int=@hex
set @dez=CAST (@hex AS int)+ 4294967296

select @hex as Hex,@int as integ, @dez as Decimalwert

sollte eigentlich den Wert 10 ergeben, wegen +4294967296 natülich nicht
ist aber der set @hex=0x82FB1B94 vorgegeben passt dies wieder

Gibt es eine einfache Umwandlungsmöglichkeit?


set "Dezimal"=CAST Hexwert AS numeric
funktioniert schonmal nicht

Danke für Eure Anregungen
Sven
Frank Kalis
2005-08-12 10:35:02 UTC
Permalink
Post by Sven Dörge
sollte eigentlich den Wert 10 ergeben, wegen +4294967296 natülich nicht
Gibt es eine einfache Umwandlungsmöglichkeit?
Ääh...
Kannst Du noch mal erklären wo jetzt genau Dein Problem liegt?
--
Frank Kalis
Microsoft SQL Server MVP
http://www.insidesql.de
Ich unterstütze PASS Deutschland e.V. (http://www.sqlpass.de)
Sven Dörge
2005-08-12 10:58:01 UTC
Permalink
Hallo Frank,
ich bekomme als String (varchar) den Wert 82FB1B94 (Hexadezimal), dies soll
ein Label sein, 10stellig. Dieses Label trägt die Nummer 2197494676 (Dezimal).
Ich muss nun den HEX-Wert in den Dezimalwert umwandeln!

Leider funktioniert eine direkte Umwandlung über Convert nicht
z.B. so: select convert(0x84fb1b94,numeric)

Habe keine Lust den String zu zerlegen und dann alles einzeln zu berechnen!
Muss doch eine einfache Methode dafür geben, oder?

Gruss
Sven
Post by Frank Kalis
Post by Sven Dörge
sollte eigentlich den Wert 10 ergeben, wegen +4294967296 natülich nicht
Gibt es eine einfache Umwandlungsmöglichkeit?
Ääh...
Kannst Du noch mal erklären wo jetzt genau Dein Problem liegt?
--
Frank Kalis
Microsoft SQL Server MVP
http://www.insidesql.de
Ich unterstütze PASS Deutschland e.V. (http://www.sqlpass.de)
Elmar Boye
2005-08-12 11:37:16 UTC
Permalink
Post by Sven Dörge
ich bekomme als String (varchar) den Wert 82FB1B94 (Hexadezimal),
dies soll ein Label sein, 10stellig. Dieses Label trägt die Nummer
2197494676 (Dezimal). Ich muss nun den HEX-Wert in den Dezimalwert
umwandeln!
Leider funktioniert eine direkte Umwandlung über Convert nicht
z.B. so: select convert(0x84fb1b94,numeric)
Habe keine Lust den String zu zerlegen und dann alles einzeln zu
berechnen! Muss doch eine einfache Methode dafür geben, oder?
Gleich mit echten Binärdaten arbeiten, anstatt einem String
(das der Inhalt binär ist zählt nicht).

Eine Funktion sollte zwar schnell geschrieben sein, noch fixer (bequemer) wäre:

DECLARE @hexstring varchar(10)
SET @hexstring = '0x84fb1b94'

DECLARE @intValue int
DECLARE @SQL nvarchar(255)

SET @SQL = N'SELECT @intValue = CAST(' + @hexstring + ' as int)'

EXEC sp_executesql @SQL, N'@intValue int OUTPUT', @intValue OUTPUT
SELECT @intValue, CAST(@intValue as binary(4))

wobei ich bei intensivem Einsatz doch mal eine Funktion testen würde.

Gruss
Elmar
Christoph Muthmann
2005-08-12 11:09:28 UTC
Permalink
Post by Frank Kalis
[snip]
sollte eigentlich den Wert 10 ergeben, wegen +4294967296 natülich
Gibt es eine einfache Umwandlungsmöglichkeit?
Ääh...
Kannst Du noch mal erklären wo jetzt genau Dein Problem liegt?
Ich denke, das eigentliche Problem ist das Wetter, welches uns allen
auf den Geist geht und weshalb morgen auch das PASS-Grillen ausfällt!


Einen schönen Tag noch,
Christoph
--
(Please post ALL replies to the newsgroup only unless indicated
otherwise)
Sven Dörge
2005-08-12 11:18:10 UTC
Permalink
Nein im ERNST! Keine Ahnung wie das schnell zu erledigen ist!
Post by Christoph Muthmann
Post by Frank Kalis
[snip]
sollte eigentlich den Wert 10 ergeben, wegen +4294967296 natülich
Gibt es eine einfache Umwandlungsmöglichkeit?
Ääh...
Kannst Du noch mal erklären wo jetzt genau Dein Problem liegt?
Ich denke, das eigentliche Problem ist das Wetter, welches uns allen
auf den Geist geht und weshalb morgen auch das PASS-Grillen ausfällt!
Einen schönen Tag noch,
Christoph
--
(Please post ALL replies to the newsgroup only unless indicated
otherwise)
Christoph Muthmann
2005-08-12 11:26:24 UTC
Permalink
Post by Sven Dörge
Nein im ERNST! Keine Ahnung wie das schnell zu erledigen ist!
Na gut!

Nur so eine Idee und sicher ausbaufähig!

declare @cmd varchar(100)
declare @myhex varchar(100)

declare @hex varbinary (4)
declare @dez numeric
declare @int int

create table t(hex varbinary(4))

Set @myhex = '0x84fb1b94'

Set @Cmd = 'insert into t(hex) (SELECT CAST(CAST('+@myhex+' AS varchar)
AS varbinary))'
print @cmd

exec (@cmd )

select @hex = hex from t

set @int=@hex
set @dez=CAST (@hex AS int)+ 4294967296

select @hex as Hex,@int as integ, @dez as Decimalwert

drop table t

Einen schönen Tag noch,
Christoph
--
(Please post ALL replies to the newsgroup only unless indicated
otherwise)
Sven Dörge
2005-08-12 11:36:03 UTC
Permalink
guter versuch!

nur mit 0x00000004 funkt's nicht!!!!


also noch sowas einbauen
if @int<0 set @dez=CAST (@hex AS int)+ 4294967296
else set @dez=CAST (@hex AS int)

stimmts?

mfg
sven
Post by Christoph Muthmann
Post by Sven Dörge
Nein im ERNST! Keine Ahnung wie das schnell zu erledigen ist!
Na gut!
Nur so eine Idee und sicher ausbaufähig!
create table t(hex varbinary(4))
AS varbinary))'
drop table t
Einen schönen Tag noch,
Christoph
--
(Please post ALL replies to the newsgroup only unless indicated
otherwise)
Sven Dörge
2005-08-12 11:43:02 UTC
Permalink
dANKE AN ALLE DIE GEHOLFEN HABEN!!!!

hier die Lösung als Procedure:

-- drop proc up_hextodec
-- exec up_hextodec '0000000A',''

create proc up_hextodec

@ein varchar (100),
@aus varchar (100) output


as

declare @cmd varchar(100)
declare @myhex varchar(100)

declare @hex varbinary (4)
declare @dez numeric
declare @int int

create table t(hex varbinary(4))

Set @myhex = '0x'+@ein

Set @Cmd = 'insert into t(hex) (SELECT CAST(CAST('+@myhex+' AS varchar)
AS varbinary))'
print @cmd

exec (@cmd )

select @hex = hex from t

set @int=@hex
if @int<0 set @dez=CAST (@hex AS int)+ 4294967296
else set @dez=CAST (@hex AS int)

set @aus=@dez

select @ein as eingabe, @hex as Hex,@int as integ, @dez as Decimalwert, @aus
as ausgabe
drop table t

RETURN
GO
Post by Sven Dörge
Hallo zusammen,
habe ein Brett vorm Kopf!!!!
sollte eigentlich den Wert 10 ergeben, wegen +4294967296 natülich nicht
Gibt es eine einfache Umwandlungsmöglichkeit?
set "Dezimal"=CAST Hexwert AS numeric
funktioniert schonmal nicht
Danke für Eure Anregungen
Sven
Frank Kalis
2005-08-12 11:56:01 UTC
Permalink
Die gleiche Idee wie Elmar. Allerdings sollte es durch den Einsatz von
BIGINT anstelle von INT passen.

DECLARE @hex VARCHAR(20)
DECLARE @stmt NVARCHAR(255)
DECLARE @int BIGINT
SET @hex = '0x84fb1b94'

SELECT @stmt = N'SELECT @int = CONVERT( BIGINT , ' + @hex + ' )'
EXEC sp_ExecuteSql @stmt, N' @int BIGINT Out', @int OUT
SELECT @int
GO

--------------------
2231049108
--
Frank Kalis
Microsoft SQL Server MVP
http://www.insidesql.de
Ich unterstütze PASS Deutschland e.V. (http://www.sqlpass.de)
Elmar Boye
2005-08-13 08:29:44 UTC
Permalink
Hallo Sven,
Post by Frank Kalis
Die gleiche Idee wie Elmar.
die er eher aus Zeitmangel postete und hier als Nachtrag eine Funktion,
die ich bereits gestern - siehe Anmerkung - als sinnvoller ansah...


CREATE FUNCTION dbo.fn_HexToDecimal
(
@hexValue varchar(32)
)
RETURNS decimal(18, 0)
AS
BEGIN
DECLARE @chars varchar(16)
DECLARE @charIndex int
DECLARE @index int
DECLARE @length int

DECLARE @value decimal(18, 0)

SET @chars = '0123456789ABCDEF'
IF @hexValue IS NULL
RETURN NULL
SET @length = LEN(@hexValue)
-- mit '0X' und ohne Präfix
IF @length > 2 AND UPPER(SUBSTRING(@hexValue, 1, 2)) = '0X'
SET @index = 3
ELSE
SET @index = 1

SET @value = 0
WHILE @index <= @length
BEGIN
SET @charIndex = CHARINDEX(SUBSTRING(@hexValue, @index, 1), @chars)

-- Kein gültiges Zeichen
IF @charIndex = 0
RETURN NULL

SET @value = @value * 16.0 + @charIndex - 1
SET @index = @index + 1
END
RETURN @value
END
GO
GRANT EXECUTE ON dbo.fn_HexToDecimal TO public
GO

-- einige Testfälle
SELECT 1 AS TestNo, dbo.fn_HexToDecimal ('0000000A') AS Value
UNION ALL SELECT 2, dbo.fn_HexToDecimal ('0X0000000A')
UNION ALL SELECT 3, dbo.fn_HexToDecimal ('A')
UNION ALL SELECT 4, dbo.fn_HexToDecimal ('0xA')
UNION ALL SELECT 5, dbo.fn_HexToDecimal ('0x82FB1B94')
UNION ALL SELECT 6, dbo.fn_HexToDecimal ('82FB1B94')
UNION ALL SELECT 7, dbo.fn_HexToDecimal ('0xFFFFFFFF')
UNION ALL SELECT 8, dbo.fn_HexToDecimal ('')
UNION ALL SELECT 9, dbo.fn_HexToDecimal ('0x')
UNION ALL SELECT 10, dbo.fn_HexToDecimal ('0x1234Z')
GO

Gruss
Elmar
Frank Kalis
2005-08-15 10:33:01 UTC
Permalink
Post by Elmar Boye
die er eher aus Zeitmangel postete und hier als Nachtrag eine Funktion,
die ich bereits gestern - siehe Anmerkung - als sinnvoller ansah...
Dein 8.ter Testfall ergibt 0 da SELECT CAST('' AS INT) 0 ist, wäre NULL
nicht angebrachter?

CREATE FUNCTION dbo.HexToDecimal (@HexToDecimal VARCHAR(20))
RETURNS BIGINT
AS
BEGIN
DECLARE @value BIGINT

SET @HexToDecimal=REPLACE(UPPER(@HexToDecimal), '0X','')

SELECT @value = 16 * ISNULL(@value,'') +
CASE
WHEN SUBSTRING (@HexToDecimal, Number, 1) BETWEEN '0' AND '9'
THEN CAST(SUBSTRING (@HexToDecimal, Number, 1) AS INT)
ELSE
CASE SUBSTRING (@HexToDecimal, Number, 1)
WHEN 'A' THEN 10
WHEN 'B' THEN 11
WHEN 'C' THEN 12
WHEN 'D' THEN 13
WHEN 'E' THEN 14
WHEN 'F' THEN 15
ELSE NULL
END
END
FROM master..spt_values
WHERE Type='P' AND Number BETWEEN 1 AND LEN(@HexToDecimal)
RETURN @value
END
GO

SELECT 1 AS TestNo, dbo.HexToDecimal ('0000000A') AS Value
UNION ALL SELECT 2, dbo.HexToDecimal ('0X0000000A')
UNION ALL SELECT 3, dbo.HexToDecimal ('A')
UNION ALL SELECT 4, dbo.HexToDecimal ('0xA')
UNION ALL SELECT 5, dbo.HexToDecimal ('0x82FB1B94')
UNION ALL SELECT 6, dbo.HexToDecimal ('84FB1B94')
UNION ALL SELECT 7, dbo.HexToDecimal ('0xFFFFFFFF')
UNION ALL SELECT 8, dbo.HexToDecimal ('')
UNION ALL SELECT 9, dbo.HexToDecimal ('0x')
UNION ALL SELECT 10, dbo.HexToDecimal ('0x1234Z')
GO
DROP FUNCTION dbo.HexToDecimal
--
Frank Kalis
Microsoft SQL Server MVP
http://www.insidesql.de
Ich unterstütze PASS Deutschland e.V. (http://www.sqlpass.de)
Elmar Boye
2005-08-15 10:46:06 UTC
Permalink
Hallo Frank,
Post by Frank Kalis
Post by Elmar Boye
die er eher aus Zeitmangel postete und hier als Nachtrag eine
Funktion, die ich bereits gestern - siehe Anmerkung - als sinnvoller
ansah...
Dein 8.ter Testfall ergibt 0 da SELECT CAST('' AS INT) 0 ist, wäre
NULL nicht angebrachter?
Ich habe da der Standardlogik entsprochen:
SELECT CAST('' AS int)
ergibt ebenfalls "0".

Gruss
Elmar

Loading...