簡體   English   中英

在單個表列中存儲多個位值

[英]Store multiple bit values in a single table column

我需要在數據庫中存儲某種星期幾的日程安排,在那里我可以安排一周中的一天或多天的記錄(比如它代表一項任務)。 我需要將它存儲在一列中,以便於保存和檢索。 然后每天我都會選擇日程表與當前星期幾匹配的記錄,例如:獲取所有日程表匹配第 7 周的記錄。

我想到的是一系列 7 位,每個位代表一周中的一天,其中 0 表示未安排,1 表示安排。 例如:“1111111”表示日常任務,“1000000”表示僅在一周的第一天運行的任務。

為了清楚起見,記錄可能會安排在我不知道的任何天數組合中,因此檢索中的唯一輸入是要搜索的工作日。

我在這里有兩個問題:

  1. 在 SQL Server 2008 中存儲此類數據的最佳方法是什么? 以一種允許根據當前星期幾輕松查詢的方式。

  2. 什么是上述方法的更好替代方案。 請我需要高效且易於實施的解決方案。

您可以將其存儲為位域,然后使用布爾邏輯運算符來檢索值

例如:

CREATE TABLE [dbo].[testBF](
    [field1] [varchar](max) NOT NULL,
    [field2] [varchar](max) NOT NULL,
    [bitfield] [int] NOT NULL CONSTRAINT [DF_testBF_bitfield]  DEFAULT ((0))
) ON [PRIMARY]

然后對於選擇:

SELECT field1, field2,
       CASE WHEN (bitfield & 1) = 1 THEN 'monday ' ELSE '' END + 
       CASE WHEN (bitfield & 2) = 2 THEN 'tuesday ' ELSE '' END +
       CASE WHEN (bitfield & 4) = 4 THEN 'wednesday ' ELSE '' END +
       CASE WHEN (bitfield & 8) = 8 THEN 'thursday ' ELSE '' END +
       CASE WHEN (bitfield & 16) = 16 THEN 'friday' ELSE '' END as [days of week]
FROM testBF

查找包含星期二標志的所有日子(星期二是第二位或 2^1 或 2)

SELECT * 
FROM aTable
WHERE (bitfield & 2) = 2

或者

SELECT * 
FROM aTable
WHERE (bitfield & 2) != 0

請注意,第二種情況下的模板適用於任何位——即星期五(第 5 位或 2^4 或 16)將是

SELECT * 
FROM aTable
WHERE (bitfield & 16) != 0

最后是一般情況...傳入一個數字(星期一為 1)你得到

SELECT * 
FROM aTable
WHERE (bitfield & POWER(2,@inNumOfWeekday-1)) != 0

這對我來說似乎是很多工作,當您可以將其保存為 5(或 7 個位字段)時,但這就是您可以做到的。

有關更多示例,請查看我為另一個問題編寫的要點:

https://gist.github.com/1846338

和答案:

https://stackoverflow.com/a/9302106/215752

您正在談論“位掩碼”。 這些是方便的設備,因為您可以對它們應用二進制數學以輕松檢查值,但它們確實需要一些設置。 再擴展一點,它看起來像這樣。

-- You will want to work with constants
DECLARE @Mon INT, @Tue INT, @Wed INT, @Thu INT, @Fri INT, @Sat INT, @Sun INT

SET @Mon = POWER(2,0) -- 1
SET @Tue = POWER(2,1) -- 2
SET @Wed = POWER(2,2) -- 4
SET @Thu = POWER(2,3) -- 8
SET @Fri = POWER(2,4) -- 16
SET @Sat = POWER(2,5) -- 32
SET @Sun = POWER(2,6) -- 64

-- Set Monday and Wednesday
UPDATE T SET Schedule = @Mon | @Wed

-- Find all tasks scheduled on Tuesday
SELECT * FROM T WHERE Schedule & @Tue = @Tue

-- Find all tasks scheduled on Tuesday and Saturday
SELECT * FROM T WHERE Schedule & @Tue | @Sat = @Tue | @Sat

從標題來看,我被引導到一個表中存在位字段並且需要轉換為單個整數字段的情況。

在下面的星期幾示例中,假設有 7 個單獨的位字段,您希望將其轉換為名為 Schedule 的(位掩碼)整數字段:

UPDATE T
SET Schedule = Mon * POWER(2,0) +
               Tue * POWER(2,1) +
               Wed * POWER(2,2) +
               Thu * POWER(2,3) +
               Fri * POWER(2,4) +
               Sat * POWER(2,5) +
               Sun * POWER(2,6)

我不確定您所說的簡單查詢是什么意思。 一旦你把它包裝在一個函數中,這一切都很容易。 簡單的臨時查詢的一個選項可能是具有易於閱讀的字符串字段並使用一些字符串操作過程來解決它。 例子:

UPDATE T SET Schedule = 'M|W|H'

SELECT * FROM T WHERE CHARINDEX(Schedule, 'M') > -1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM