J'ai une valeur bitmask stockée sous forme d'int dans SQL. J'aimerais transformer cette valeur dans une liste séparée par des virgules des valeurs contenues dans la valeur bitmask.
Donc, par exemple, les résultats peuvent ressembler à ce que: p> est un moyen d'accomplir cela dans une déclaration SQL? p> Ceci est SQL Server 2008. P> P>
3 Réponses :
Cela devrait fonctionner:
SELECT id, name, bitMaskValue, SUBSTRING( CASE WHEN bitMaskValue & 1 = 1 THEN ',1' ELSE '' END + CASE WHEN bitMaskValue & 2 = 2 THEN ',2' ELSE '' END + CASE WHEN bitMaskValue & 4 = 4 THEN ',4' ELSE '' END + CASE WHEN bitMaskValue & 8 = 8 THEN ',8' ELSE '' END , 2, 64) As [values] FROM yourTable
Ceci est exactement ce que je cherchais! Merci beaucoup.
declare @I integer = 2117 Declare @v varChar(32) = '' Declare @Bit tinyInt = 0 while @I > 0 Begin Set @v += case @I %2 WHen 1 Then str(@bit,2,1) + ',' else '' End Set @Bit += 1 Set @i /= 2 End Select case When len(@v) > 0 Then left(@v, len(@v) -1) else '' End
Merci. J'ai créé une fonction pour cela et cela a bien fonctionné. J'ai changé la sortie de str (@ bit, 2,1) code> à
str (puissance (2, @ bit), 2,1) code> pour correspondre à ce dont j'avais besoin.
BTW, je suis totalement d'accord avec le commentaire de @ maeger à votre question. Ce n'est pas une utilisation appropriée / bonne utilisation PF un serveur de base de données ...
CTE + XPath Way CODE>:
set nocount on
declare @t as table(id int, name varchar(100), bitMaskValue int)
insert into @t(id, name, bitMaskValue) values(1,'Bob',5)
insert into @t(id, name, bitMaskValue) values(2,'Mary',13)
insert into @t(id, name, bitMaskValue) values(3,'Stan',11)
;with cte(num) as
(
select 1
union all
select num*2
from cte
)
select
id,
name,
bitMaskValue,
stuff((
select cast((
select isBitSet
from
(
select top 31 num,
case
when bitMaskValue & num = num then ',' + cast(num as varchar(10))
else null
end isBitSet
from cte
) tmp
where isBitSet is not null
for xml path('')) as xml).value('.', 'VARCHAR(max)')
), 1, 1, '') bitSet
from @t
Cette question ne montre aucun effort de recherche. Il est important de faire vos devoirs b>. Dites-nous ce que vous avez trouvé et pourquoi i> b> Cela n'a pas répondu à vos besoins. Cela démontre que vous avez pris le temps d'essayer de vous aider, cela nous évite de réitérer des réponses évidentes, et la plupart d'entre elles vous permettent d'obtenir une réponse plus spécifique et pertinente. FAQ .
Juste un fyi, vous abusez vraiment votre SGBDM. Les bases de données sont censées fonctionner vraiment bien i> avec des clés étrangères. J'espère que vous avez eu des exigences assez précises avant d'ajouter un bitmask à votre dossier, plutôt que de normaliser correctement les données et d'utiliser une table de jonction typique.
Je suis complètement d'accord avec toi @meagar. Dans mon cas, j'ai des données héritées (le bitmaskvalue) que j'essaie simplement de normaliser et d'appuyer sur une autre source qui prenne des valeurs délimitées sur des virgules. Je pensais que c'était un casse-tête intéressant et que je ne trouvais aucune solution de SQL uniquement via Google ou que je me suis donc demandé quelles sont les bonnes solutions que les gens pourraient avoir.
@meagar Ce n'est peut-être pas un bon usage de SGBDM, mais même Microsoft utilise un bitmask dans ses tables internes (c'est-à-dire reporterver..schedule). La question peut ne pas couvrir un scénario de meilleure pratique, mais un scénario qui existe néanmoins. J'ai trouvé la question très pertinente et les réponses m'ont aidé beaucoup.