我正在使用SQL Server 2012 Express。我有一个长度为32位的1和0的字符串
01010010000100010111001101110011
如何在SQL脚本中将其转换为有符号十进制数?
目前我使用一个网络工具在线为我的答案,我目前的搜索并没有引导我到我需要的答案。
如果使用一个统计表,则可以使用单个T-SQL语句执行转换:
;WITH Tally(i) AS (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS i
FROM (VALUES (0), (0), (0), (0), (0), (0), (0), (0)) a(n)
CROSS JOIN (VALUES (0), (0), (0), (0)) b(n)
)
SELECT SUM(t.v) AS DecimalNumber
FROM (
SELECT POWER(CAST(SUBSTRING(x.d, i, 1) AS DECIMAL(10,0)) * 2, 32 - i)
FROM (VALUES ('01010010000100010111001101110011')) x(d)
CROSS JOIN Tally) AS t(v)
解释:
-
Tally
是一个表表达式,返回1-32之间的所有值。 - 使用这些值,我们可以使用
SUBSTRING
提取二进制字符串中的每一个数字。 使用 - 使用
SUM
,我们可以将所有单独的十进制数字相加以得到预期的结果。
POWER
数学函数可以将每个单独的二进制数转换为十进制数。演示
你可以尝试如下-
DECLARE @Binary VARCHAR(100) = '01010010000100010111001101110011';
DECLARE @characters CHAR(36),
@result BIGINT,
@index SMALLINT,
@base BIGINT;
SELECT @characters = '0123456789abcdefghijklmnopqrstuvwxyz',
@result = 0,
@index = 0,
@base = 2;
WHILE @index < LEN(@Binary)
BEGIN
SELECT @result = @result + POWER(@base, @index) * (CHARINDEX(SUBSTRING(@Binary, LEN(@Binary) - @index, 1), @characters) - 1);
SET @index = @index + 1;
END
SELECT @result;
这将帮助您从任何基数(我使用@base as 2
二进制)转换为基数10。从最右边开始,移到最左边,直到没有数字了。转换为(base ^ index) *数字
除了Giorgos Betsos的回复见以下ITVF功能:
CREATE FUNCTION [dbo].[udf_BinaryToDecimal]
(
@Binary VARCHAR(31)
)
RETURNS TABLE AS RETURN
WITH Tally (n) AS
(
--32 Rows
SELECT TOP (LEN (@Binary)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1
FROM (VALUES (0),(0),(0),(0)) a(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
)
SELECT
SUM(SUBSTRING(REVERSE(@Binary),n+1,1) * POWER(2,n)) TenBase
FROM Tally
/*How to Use*/
SELECT TenBase
FROM udf_BinaryToDecimal ('01010010000100010111')
/*Result -> 336151*/
我必须将这段代码添加到Abhishek的代码示例的末尾,以获得我需要的有符号数字。
DECLARE @MyNewExValue INT
IF @result > 2147483647
BEGIN
SET @result = @result - (2147483648 * 2)
END
SET @MyNewExValue = @result
SELECT @MyNewExValue
此解决方案适用于任何(bigint)长度的二进制字符串:
DECLARE @input varchar(max) =
'01010010000100010111001101110011'
;WITH N(V) AS
(
SELECT
ROW_NUMBER()over(ORDER BY (SELECT 1))
FROM
(VALUES(1),(1),(1),(1))M(a),
(VALUES(1),(1),(1),(1))L(a),
(VALUES(1),(1),(1),(1))K(a)
)
SELECT SUM(SUBSTRING(REVERSE(@input),V,1)*POWER(CAST(2 as BIGINT), V-1))
FROM N
WHERE V <= LEN(@input)
(源)
应该注意的是,上面最受欢迎的解决方案仅适用于长度为32位的二进制字符串,并且字符串'00000000000000000000000000000000'
返回1
。