[ad_1]
Passer un moment dense/senior aujourd’hui…
J’ai une requête SQL (héritée) exécutée sur un cte qui produit désormais des lignes numérotées de 1 à 16384. Je m’attends à ce qu’elle génère des lettres de colonne dans la plage “A” à “XFC” (générée précédemment “A” à “ZZ “)
Cela devrait fonctionner
SELECT l, CASE WHEN l >= 703 THEN Char(65 + (l - 703) / 702 % 702) ELSE '' END + CASE WHEN l >=27 then Char(65 + (l - 27) / 26 % 26) ELSE '' END + Char(65 + (l - 1) % 26) FROM eFinal WHERE l < 16384 ORDER BY l;
En fait, il fait travail – JUSQU’À ce que nous arrivions à la ligne 6787 – au lieu de renvoyer “JAA”, il revient à “IAA” (jusqu’à “IAZ” et à partir de là, il fait des choses étranges et merveilleuses (y compris des caractères non-ascii))
Je peux le contourner avec
SELECT l, (CASE WHEN l >= 6787 THEN Char((65 + (l - 703) / 702 % 702) + 1) WHEN l >= 703 THEN Char(65 + (l - 703) / 702 % 702) ELSE '' END) + (CASE WHEN l > 27 THEN (Char(65 + (l - 27) / 26 % 26)) ELSE '' END) +(Char(65 + (l - 1) % 26)) FROM eFinal WHERE l < 16384 ORDER BY l;
Ce qui fonctionne jusqu’à “XFC”.
Ce que je ne comprends pas, c’est… pourquoi ?
J’ai du mal à comprendre la signification de 6786 en tant que nombre clé – même si j’ai été surexcité lorsque j’ai réalisé qu’il s’agissait de 26 x 255, mais l
est-ce qu’un bigint n’est pas pertinent ?
Ce que j’ai essayé :
Code complet pour reproduire le comportement
;with cte1 AS (select n from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1) ) AS X(n)) ,cte2 AS (SELECT a.n FROM cte1 a CROSS JOIN cte1 b) -- 10*10 ,cte3 AS (SELECT a.n FROM cte1 a CROSS JOIN cte2 b) -- 10*100 ,cte4 AS (SELECT a.n FROM cte2 a CROSS JOIN cte3 b ) -- 1000*100 ,eFinal AS (SELECT l = ROW_NUMBER() OVER (ORDER BY a.n) FROM cte2 a CROSS JOIN cte3 b ) SELECT l, CASE WHEN l >= 703 THEN Char(65 + (l - 703) / 702 % 702) ELSE '' END + CASE WHEN l >=27 then Char(65 + (l - 27) / 26 % 26) ELSE '' END + Char(65 + (l - 1) % 26) FROM eFinal --WHERE l < 16384 where l BETWEEN 6780 AND 6790 ORDER BY l;
Solution 1
Parce que ton calcul est faux ! 😀
DECLARE @cnt INT = 6785; WHILE @cnt < 6789 BEGIN SELECT @cnt , (@cnt - 27) / (26 * 26) , CASE WHEN (@cnt - 27 / (26 * 26)) > 0 THEN CHAR(65 + ((@cnt - 27) / (26 * 26))) ELSE '' END , Char(65 + (@cnt - 27) / 26 % 26) , Char(65 + (@cnt - 1) % 26) SET @cnt = @cnt + 1; END
[ad_2]
コメント