Перетворити ціле число на шістнадцяткове та шістнадцяткове на ціле


78

Отже, у мене цей запит працює (де signal_dataстовпець) у Sybase, але він не працює в Microsoft SQL Server:

HEXTOINT(SUBSTRING((INTTOHEX(signal_data)),5,2)) as Signal

У мене також є в Excel (де A1міститься значення):

=HEX2DEC(LEFT(DEC2HEX(A1),LEN(DEC2HEX(A1))-2))

Хтось знає, як би я це зробив у SQL Server?

Відповіді:


119

Перетворити INT на шістнадцятковий:

SELECT CONVERT(VARBINARY(8), 16777215)

Перетворити hex на INT:

SELECT CONVERT(INT, 0xFFFFFF)

Оновлення 2015-03-16

Наведений приклад має обмеження, що він працює лише тоді, коли значення HEX задано як цілочисельний літерал. Для повноти, якщо значення для перетворення є шістнадцятковим рядком (наприклад, знайденим у стовпці varchar), використовуйте:

-- If the '0x' marker is present:
SELECT CONVERT(INT, CONVERT(VARBINARY, '0x1FFFFF', 1))

-- If the '0x' marker is NOT present:
SELECT CONVERT(INT, CONVERT(VARBINARY, '1FFFFF', 2))

Примітка: Рядок повинен містити парну кількість шістнадцяткових цифр. Непарна кількість цифр дасть помилку.

Детальніше можна знайти в розділі "Бінарні стилі" в CAST і CONVERT (Transact-SQL) . Я вважаю, що потрібен SQL Server 2008 або пізнішої версії.


8
Перетворивши його на VARBINARY, ви отримаєте дані у шістнадцятковому значенні. Струнні операції на ньому виконувати не можна
— Паван

1
@ Білл Карвін, Паван прав. Sql Server 2008 може зробити це за допомогою convertфункції, але 2005 і нижче не можуть.
— Бен

2
При використанні 8-символьної шістнадцяткової лінії, наприклад з ARGB, перетворіть у BIGINT замість INT. Максимальне значення для INT становить лише 2 147 483 647, або 7FFFFFFF. Обережно, використовуючи INT, повернення назад до hex буде працювати, але результати відрізняються від Hex2Dec Excel.
— DenverJT

SELECT CONVERT(INT, CONVERT(varbinary, '01', 2))повертається 12337 (SQL Server 2005)
— Ян Бойд,

Перші приклади не перетворюються в шістнадцяткові: вони перетворюються в двійкові. (Двійкове значення існує незалежно від будь-якої числової бази: Числова база має сенс лише в контексті рядкового подання.) (Крім того, параметр не повинен бути буквальним (хоча він повинен бути цілим числом.)) Вони можуть здаватися наче перетворюються в шістнадцяткову, оскільки при перетворенні двійкового файлу в рядок (наприклад, для його відображення) він за замовчуванням представляє його в шістнадцятковому. (Це може бути використано для перетворення в шістнадцяткову систему, як показано у відповіді @ KipBryan, але відповіді DenNukem та wndproc простіші.)
— Джон Б. Ламб,

46

Власне, вбудована функція має ім'я master.dbo.fn_varbintohexstr.

Так, наприклад:

SELECT 100, master.dbo.fn_varbintohexstr(100)

Дає вам

100 0x00000064


3
Дивіться dba.stackexchange.com/questions/46910/… про мінуси.
— Вадзім

@Vadzim Більшість "мінусів" - окрім відсутності документації / специфікації - звучать як BS !.
— користувач2864740

28

Еквіваленти SQL Server функціям DEC2HEX, HEX2DEC на основі рядків Excel:

--Convert INT to hex string:
PRINT CONVERT(VARCHAR(8),CONVERT(VARBINARY(4), 16777215),2) --DEC2HEX

--Convert hex string to INT:
PRINT CONVERT(INT,CONVERT(VARBINARY(4),'00FFFFFF',2)) --HEX2DEC


13

Це можливо за допомогою функції FORMAT, доступної на SQL Server 2012 і вище

select FORMAT(10,'x2')

Призводить до:

0a

5

Традиційний 4-бітний шістнадцятковий код досить прямий. Шістнадцятковий рядок у ціле число (припускаючи, що значення зберігається у полі, що називається FHexString):

CONVERT(BIGINT,CONVERT(varbinary(4),
                (SELECT master.dbo.fn_cdc_hexstrtobin(

                    LEFT(FMEID_ESN,8)                       
                ))
                ))

Ціле число до шістнадцяткового рядка (припускаючи, що значення зберігається у полі, що називається FInteger):

(SELECT master.dbo.fn_varbintohexstr(CONVERT(varbinary,CONVERT(int,
                    FInteger
                ))))

Важливо зазначити, що коли ви починаєте використовувати бітові розміри, які спричиняють спільний доступ до регістрів, особливо на машині Intel, ваші високі та низькі та ліві та права в регістрах будуть помінені місцями через незначну природу Intel. Наприклад, коли використовується varbinary (3), ми говоримо про 6-символьну шістнадцяткову форму. У цьому випадку ваші біти поєднуються як такі індекси справа наліво "54,32,10". В системі Intel ви очікували б "76,54,32,10". Оскільки ви використовуєте лише 6 з 8, вам слід пам’ятати, що робити заміни потрібно самостійно. "76,54" вважатиметься вашим лівим, а "32,10" - вашим правим. Кома розділяє ваш високий і низький. Intel міняє місцями максимуми і мінімуми, потім ліворуч і праворуч. Отже, щоб зробити перетворення ... зітхайте, ви повинні поміняти їх місцями, наприклад,

(SELECT master.dbo.fn_replvarbintoint(
                CONVERT(varbinary(3),(SELECT master.dbo.fn_cdc_hexstrtobin(
                    --intel processors, registers are switched, so reverse them 


                    ----second half
                    RIGHT(FHex8,2)+ --0,1 (0 indexed)
                    LEFT(RIGHT(FHex8,4),2)+ -- 2,3 (oindex)
                    --first half
                    LEFT(RIGHT(FHex8,6),2) --4,5

                )))
                ))

Це дещо складно, тому я намагався б зберегти свої перетворення в 8 символьних шістнадцяткових символів (varbinary (4)).

Таким чином, це має відповісти на ваше запитання. Всебічно.


5

Ось функція для SQL-сервера, яка перетворює цілочисельне значення у його шістнадцяткове представлення як varchar. Це має бути легко адаптуватися до інших типів баз даних

Наприклад:

SELECT dbo.ToHex(4095) --> FFF

SQL:

CREATE FUNCTION ToHex(@value int)
RETURNS varchar(50)
AS
BEGIN
    DECLARE @seq char(16)
    DECLARE @result varchar(50)
    DECLARE @digit char(1)
    SET @seq = '0123456789ABCDEF'

    SET @result = SUBSTRING(@seq, (@value%16)+1, 1)

    WHILE @value > 0
    BEGIN
        SET @digit = SUBSTRING(@seq, ((@value/16)%16)+1, 1)

        SET @value = @value/16
        IF @value <> 0 SET @result = @digit + @result
    END 

    RETURN @result
END
GO

Це працює! Ідеально! Вам просто потрібно замінити "IF @ value 0" на "IF @ value <> 0"
— M07

Мені подобається це рішення, оскільки воно легко модифікується на ще більш потужне. Я подав такий приклад рішення використання довжини послідовності як основи.
— Грег

3

Використовуйте master.dbo.fnbintohexstr(16777215)для перетворення у varcharподання.


1
select master.sys.fn_varbintohexstr(1)у 2008 році
— еккіс

2
Declare @Dato xml
Set @Dato = Convert(xml, '<dato>FF</dato>')
Select Cast( rw.value( 'xs:hexBinary( text()[1])' , 'varbinary(max)' ) as int ) From @Dato.nodes('dato') as T(rw)

2

Відповідь Максима Козленка приємний і може бути дещо змінений для обробки кодування числового значення до будь-якого формату коду. Наприклад:

CREATE FUNCTION [dbo].[IntToAlpha](@Value int)
RETURNS varchar(30)
AS
BEGIN
    DECLARE @CodeChars varchar(100) 
    SET @CodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    DECLARE @CodeLength int = 26
    DECLARE @Result varchar(30) = ''
    DECLARE @Digit char(1)

    SET @Result = SUBSTRING(@CodeChars, (@Value % @CodeLength) + 1, 1)
    WHILE @Value > 0
    BEGIN
        SET @Digit = SUBSTRING(@CodeChars, ((@Value / @CodeLength) % @CodeLength) + 1, 1)
        SET @Value = @Value / @CodeLength
        IF @Value <> 0 SET @Result = @Digit + @Result
    END 

    RETURN @Result
END

Отже, така велика кількість, як 150 мільйонів, стає лише 6 символами (150 000 000 = "MQGJMU")

Ви також можете використовувати різні символи в різних послідовностях як пристрій для шифрування. Або передайте символи коду та довжину символів і використовуйте як метод соління для шифрування.

І навпаки:

CREATE FUNCTION [dbo].[AlphaToInt](@Value varchar(7))
RETURNS int
AS
BEGIN
    DECLARE @CodeChars varchar(100) 
    SET @CodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    DECLARE @CodeLength int = 26
    DECLARE @Digit char(1)
    DECLARE @Result int = 0
    DECLARE @DigitValue int
    DECLARE @Index int = 0
    DECLARE @Reverse varchar(7)
    SET @Reverse = REVERSE(@Value)

    WHILE @Index < LEN(@Value)
    BEGIN
        SET @Digit = SUBSTRING(@Reverse, @Index + 1, 1)
        SET @DigitValue = (CHARINDEX(@Digit, @CodeChars) - 1) * POWER(@CodeLength, @Index)
        SET @Result = @Result + @DigitValue
        SET @Index = @Index + 1
    END 
    RETURN @Result

2

Максим Козленко має гарне рішення, і інші наближаються до того, щоб розкрити весь його потенціал, але потім повністю пропускають, зрозумівши, що ви можете визначити будь-яку послідовність символів і використовувати його довжину як основу . Ось чому мені подобається ця трохи модифікована версія його рішення, оскільки вона може працювати для бази 16, або бази 17 і т.д.

Наприклад, що робити, якщо ви хотіли букви та цифри, але не подобається I, що я схожий на одиниці, а O - як 0. Ви можете визначити будь-яку послідовність таким чином. Нижче наведена форма "Основи 36", яка пропускає I і O, щоб створити "модифіковану основу 34". Скасуйте коментар шістнадцяткового рядка, а не виконайте його як шістнадцятковий.

declare @value int = 1234567890

DECLARE @seq varchar(100) = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ' -- modified base 34
--DECLARE @seq varchar(100) = '0123456789ABCDEF' -- hex
DECLARE @result varchar(50)
DECLARE @digit char(1)
DECLARE @baseSize int = len(@seq)
DECLARE @workingValue int = @value

SET @result = SUBSTRING(@seq, (@workingValue%@baseSize)+1, 1)

WHILE @workingValue > 0
BEGIN
    SET @digit = SUBSTRING(@seq, ((@workingValue/@baseSize)%@baseSize)+1, 1)

    SET @workingValue = @workingValue/@baseSize
    IF @workingValue <> 0 SET @result = @digit + @result
END 

select @value as Value, @baseSize as BaseSize, @result as Result

Значення, розмір бази, результат

1234567890, 34, T5URAA

Я також перемістив значення до робочого значення, а потім працюю з копії робочого значення, як особисті уподобання.

Нижче наведено додаткове для зворотного перетворення для будь-якої послідовності, з основою, визначеною як довжина послідовності.

declare @value varchar(50) = 'T5URAA'

DECLARE @seq varchar(100) = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ' -- modified base 34
--DECLARE @seq varchar(100) = '0123456789ABCDEF' -- hex
DECLARE @result int = 0
DECLARE @digit char(1)
DECLARE @baseSize int = len(@seq)
DECLARE @workingValue varchar(50) = @value

DECLARE @PositionMultiplier int = 1
DECLARE @digitPositionInSequence int = 0

WHILE len(@workingValue) > 0
BEGIN
    SET @digit = right(@workingValue,1)
    SET @digitPositionInSequence = CHARINDEX(@digit,@seq)
    SET @result = @result + ( (@digitPositionInSequence -1) * @PositionMultiplier)

    --select @digit, @digitPositionInSequence, @PositionMultiplier, @result

    SET @workingValue = left(@workingValue,len(@workingValue)-1)
    SET @PositionMultiplier = @PositionMultiplier * @baseSize
END 

select @value as Value, @baseSize as BaseSize, @result as Result

1

Дано:

declare @hexStr varchar(16), @intVal int

IntToHexStr:

select @hexStr = convert(varbinary, @intVal, 1)

HexStrToInt:

declare
    @query varchar(100),
    @parameters varchar(50)

select
    @query = 'select @result = convert(int,' + @hb + ')',
    @parameters = '@result int output'

exec master.dbo.Sp_executesql @query, @parameters, @intVal output

0
IIF(Fields!HIGHLIGHT_COLOUR.Value="","#FFFFFF","#" & hex(Fields!HIGHLIGHT_COLOUR.Value) & StrDup(6-LEN(hex(Fields!HIGHLIGHT_COLOUR.Value)),"0"))

Працює для мене як вираз у кольорі шрифту


0

Щоб перетворити шістнадцяткові рядки в INT, я використовував це раніше. Його можна змінити, щоб перетворити будь-яку базу на INT фактично (восьмеричну, двійкову, що завгодно)

Declare @Str varchar(200)
Set @str = 'F000BE1A'

Declare @ndx int
Set @ndx = Len(@str)
Declare @RunningTotal  BigInt
Set @RunningTotal = 0

While @ndx > 0
Begin
    Declare @Exponent BigInt
    Set @Exponent = Len(@Str) - @ndx

    Set @RunningTotal = @RunningTotal + 

    Power(16 * 1.0, @Exponent) *
    Case Substring(@str, @ndx, 1)
        When '0' then 0
        When '1' then 1
        When '2' then 2 
        When '3' then 3
        When '4' then 4
        When '5' then 5
        When '6' then 6
        When '7' then 7
        When '8' then 8
        When '9' then 9
        When 'A' then 10
        When 'B' then 11
        When 'C' then 12
        When 'D' then 13
        When 'E' then 14
        When 'F' then 15
    End
    Set @ndx = @ndx - 1
End

Print @RunningTotal

0

Нижче наведено дві функції: dbo.HexToInt і dbo.IntToHex, я використовую їх для такого перетворення:

if OBJECT_ID('dbo.HexToInt') is not null
    drop function dbo.HexToInt
GO
create function dbo.HexToInt (@chars varchar(max))
returns int
begin
    declare @char varchar(1), @len int, @i int, @r int, @tmp int, @pow int
    set @chars = RTRIM(LTRIM(@chars))
    set @len = LEN(@chars)
    set @i = 1
    set @r = 0
    while @i <= @len
    begin
        set @pow = @len - @i
        set @char = SUBSTRING(@chars, @i, 1)
        if @char = '0'
            set @tmp = 0
        else if @char = '1'
            set @tmp = 1
        else if @char = '2'
            set @tmp = 2
        else if @char = '3'
            set @tmp = 3
        else if @char = '4'
            set @tmp = 4
        else if @char = '5'
            set @tmp = 5
        else if @char = '6'
            set @tmp = 6
        else if @char = '7'
            set @tmp = 7
        else if @char = '8'
            set @tmp = 8
        else if @char = '9'
            set @tmp = 9
        else if @char = 'A'
            set @tmp = 10
        else if @char = 'B'
            set @tmp = 11
        else if @char = 'C'
            set @tmp = 12
        else if @char = 'D'
            set @tmp = 13
        else if @char = 'E'
            set @tmp = 14
        else if @char = 'F'
            set @tmp = 15
        set @r = @r + @tmp * POWER(16,@pow)
        set @i = @i + 1     
    end
    return @r
end

І другий:

if OBJECT_ID('dbo.IntToHex') is not null
    drop function dbo.IntToHex
GO
create function dbo.IntToHex (@val int)
returns varchar(max)
begin
    declare @r varchar(max), @tmp int, @v1 int, @v2 int, @char varchar(1)
    set @tmp = @val
    set @r = ''
    while 1=1
    begin
        set @v1 = @tmp / 16
        set @v2 = @tmp % 16
        if @v2 = 0
            set @char = '0'
        else if @v2 = 1
            set @char = '1'
        else if @v2 = 2
            set @char = '2'
        else if @v2 = 3
            set @char = '3'
        else if @v2 = 4
            set @char = '4'
        else if @v2 = 5
            set @char = '5'
        else if @v2 = 6
            set @char = '6'
        else if @v2 = 7
            set @char = '7'
        else if @v2 = 8
            set @char = '8'
        else if @v2 = 9
            set @char = '9'
        else if @v2 = 10
            set @char = 'A'
        else if @v2 = 11
            set @char = 'B'
        else if @v2 = 12
            set @char = 'C'
        else if @v2 = 13
            set @char = 'D'
        else if @v2 = 14
            set @char = 'E'
        else if @v2 = 15
            set @char = 'F'
        set @tmp = @v1 
        set @r = @char + @r
        if @tmp = 0
            break
    end
    return @r
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.