In table users
I have a column username
of datatype varchar(50)
. The table has no records. I insert a new record with A
for the username. The following returns what I would expect:
SELECT username, LEN(username)
FROM users
WHERE id = 1 -- returns: A, 1
So far so good.
Now I update table users from a trigger on another table, using the value from CONTEXT_INFO()
:
set @context = cast('B' as varbinary(128))
set CONTEXT_INFO @context
update some_other_table
set x = 'y'
where id = 97
In the trigger for some_other_table
I do:
DECLARE @context VARCHAR(128)
SELECT
@context = CAST(CONTEXT_INFO() AS VARCHAR(128))
FROM
master.dbo.SYSPROCESSES
WHERE
SPID = @@SPID
DECLARE @user VARCHAR(50) = LEFT(@context, 50)
UPDATE users
SET username = LTRIM(RTRIM(@user))
WHERE id = 1
The username is correctly set to "B", but the following now returns 50:
SELECT
username, LEN(username)
FROM
users
WHERE
id = 1 -- returns: B, 50
The solution, when populating the context, is to do:
set @context = cast('B' + replicate(' ', 126) as varbinary(128))
But why do I need to do this?
When I don't pad the CONTEXT_INFO
with spaces what is happening that updating using its value will cause the resulting length to be 50 (even if I ltrim
and rtrim
the single character value before updating)?
And why must I pad my CONTEXT_INFO
to 127 bytes total, not 128? For every character over 127, 1 character is truncated from the value originally set on CONTEXT_INFO
Note: ANSI_PADDING is enabled