我正在使用一个 SQL Server 数据库,该数据库有一列包含二进制数。
但是,二进制数存储为
VARCHAR
。
我需要将
VARCHAR
转换为其数字表示形式,以便我可以进行进一步的计算。
例如我想将字符串
"0010"
转换为数值2
。
但是尝试将字符串
CAST
作为 int
给我值 10
相反。
对于如何在 SQL 中进行此转换有什么建议吗?
下面的 iTVF 将解决这个问题,OP 在与上述问题相关的评论中进一步解释了这一点。
CREATE FUNCTION dbo.UnmaskWeeks
(@WeekMask VARCHAR(64))
/*********************************************************************************************
Purpose:
Given a "Week Mask" of exactly 52 characters where a "1" is a "Week of Interest" and a "0" is
not and "Week 1" is the right-most character, return the "Weeks of Interest" as a list in a
single column.
----------------------------------------------------------------------------------------------
Usage Examples:
--===== Single value usage.
-- The following example returns a column called "WeekNumber" containing the values of
-- 51, 4, and 1. Remember, the right-most character is "Week 1".
SELECT WeekNumber
FROM dbo.UnmaskWeeks ('0100000000000000000000000000000000000000000000001001')
;
--===== Usage for a column in a table.
-- The RowPK is the column that uniquely identifies each row, which is necessary because
-- this function will return multiple rows if multiple weeks are contain in the mask for
-- any given row.
SELECT st.RowPK, uw.WeekNumber
FROM dbo.SomeTable st
OUTER APPLY dbo.UnmaskWeeks (st.SomeWeekMaskColumn) uw
;
----------------------------------------------------------------------------------------------
Programmer Notes:
1. This is a high-performance iTVF (Inline Table Valued Function) that will work in all
versions of SQL Server from 2005 and up.
2. The week numbers are return in the default of occurance from left to right in the string.
In other words, they will be numerically descending. If some other order is required,
do that externally of the this function.
3. If the length of @WeekMask is not exactly 52 characters, a row will not be returned. To
have a RowPK return with a NULL for the WeekNumber, you must use OUTER APPLY as in the
the Example Usage section above or no row will be returned, which may be the desired
result.
----------------------------------------------------------------------------------------------
Revision History:
Rev 00 - 04 Jan 2024 - Jeff Moden
- Initial creation and unit test.
Ref: https://stackoverflow.com/questions/77759453/convert-a-binary-representation-of-a-number-stored-as-varchar-to-int
*********************************************************************************************/
RETURNS TABLE WITH SCHEMABINDING AS
RETURN WITH
E1(N) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1))E0(N)) --Up to 8 rows
,Tally(N) AS (--==== This is a super small version of Itzik Ben-Gan's GETNUMS() FUNCTION
SELECT TOP(52)
N = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM E1 a,E1 b --1 to 8^2 or 64 rows max
)
SELECT WeekNumber = 53-t.N
FROM Tally t
WHERE LEN(@WeekMask) = 52 --Return nothing if the week mask isn't the correct length
AND ASCII(SUBSTRING(@WeekMask,t.N,1)) = 49 --ASCII trick for a little extra performance
;
GO