Simple confusion with DATALENGTH() DATALENGTH() function returns the length of the data in BYTES.

The table is like this:

create table tb3 
( 
id int, 
id2 varchar(100), 
nome varchar(200)
)

| id      | id2   | nome  |   |
|---------|-------|-------|---|
| 1       | 1     | r     |   |
| 1       | 11    | r1    |   |
| 1       | 111   | r11   |   |
| 1       | 1111  | r111  |   |
| 1       | 11111 | r1111 |   |
| 11      | 11111 | r1111 |   |
| 1111111 | 11111 | r1111 |   |


but when i run it like this:

select DATALENGTH(id), DATALENGTH(id2), DATALENGTH(nome) from tb3

| (No column name) | (No column name) | (No column name) |   |
|------------------|------------------|------------------|---|
| 4                | 1                | 1                |   |
| 4                | 2                | 2                |   |
| 4                | 3                | 3                |   |
| 4                | 4                | 4                |   |
| 4                | 5                | 5                |   |
| 4                | 5                | 5                |   |
| 4                | 5                | 5                |  


Why it says each varchar character is using only 1 byte?
If i'm not mistaken, a varchar uses 2 bytes + number of characters.
The 'DATALENGTH()' function returns the length of just the data, those extra two bytes are considered "meta-data" - information about the data and/or its storage.

You get the same value if you pass the function a string literal (DATALENGTH('12345') returns 5) - this wouldn't be the case if the function accounted for storage overheads as well as the string's content.

To account for storage overhead the DATALENGTH function would need to know or be able to derive where a value has come from, and the structure of that location, if the data is compressed, etc., and accounting for all that would make the function far less efficient.