Quantcast
Channel: Tech Morsels - Database Engine
Viewing all articles
Browse latest Browse all 5

Issues with Len() function

$
0
0

Change Data Capture if enabled on Database & Tables stores pre and post modification data in separate set of tables. In our project we were using this data regenerate Insert, Update and Delete Statement.

If there are 10 columns and if 2 columns are updated, CDC maintains bitmap for indicating all columns that are modified. To find out exact column we were doing & (And) operation. And below issue was found during testing.

DecimalBinaryHexLength (in Bytes)
1000000010x11 Byte
2000000100x21 Byte
4000001000x41 Byte
8000010000x81 Byte
16000100000x101 Byte
32001000000x201 Byte
64010000000x401 Byte
128100000000x801 Byte

 

SelectLEN(1),LEN(2),LEN(4),LEN(8),LEN(16),LEN(32),LEN(64),LEN(128)
What would be output of such query? If you thought it would be 1 (since they are all 1 byte) it is wrong. 
Instead treat them as Character data type and SQL would give result as 
  • 1 for all single digit numbers (1,2,4,8)
  • 2 for all double digit numbers (16,32)
  • 3 for all triple digit numbers (128)

Now it gets more interesting..

SelectLEN(0x1), LEN(0x2), LEN(0x4), LEN(0x8), LEN(0x10), LEN(0x20), LEN(0x40) , LEN(0x80)

    • LEN(0x1)  - 1 Byte
    • LEN(0x2)  - 1 Byte
    • LEN(0x4)  - 1 Byte
    • LEN(0x8)  - 1 Byte
    • LEN(0x10) -1 Byte
    • LEN(0x20) –0 Byte  
    • LEN(0x40) – 1 Byte
    • LEN(0x80) – 1 Byte

Now see above, Len(0x20) is 0 (Zero) bytes??  What about LEN(0X200) – 2 Bytes, this seems correct.

It happens only with LEN(0X20) that is always 0.

What could be the reason? Try this

Select    CHAR(0x1) as [0x1], CHAR(0x2) as [0x2], CHAR(0x4) as [0x4],
        CHAR(0x8) as [0x8], CHAR(0x10) as [0x10],CHAR(0x20) as [0x20],
        CHAR(0x40) as [0x40], CHAR(0x80) as [0x10]

 

image

Notice above 0x20 there is nothing implying 0x20 is “ “ (space).

May be what is happing is when we say Len(0x20), since it is space SQL Server truncates (trailing spaces) and finds out length. So instead of 1 we get 0.

From SelectLEN(1),LEN(2),LEN(4),LEN(8),LEN(16),LEN(32),LEN(64),LEN(128) we see that even though data type passed is integer, SQL treats them as Character data and finds length.

I think length is more biased towards character data even though it supports other data types as well.

Well what is workaround, Workaround is to use DataLength instead of Len() function

SelectDATALENGTH(0x1), DATALENGTH(0x2), DATALENGTH(0x4), DATALENGTH(0x8), DATALENGTH(0x10), DATALENGTH(0x20), DATALENGTH(0x40) , DATALENGTH(0x80)

Hope this is useful tip

Until next time, keep in touch.

-Guru


Viewing all articles
Browse latest Browse all 5

Trending Articles