在表users
我有一列username
数据类型varchar(50)
。该表没有记录。我用A
作为用户名插入新记录。以下回报我所期望的:SQL Server,CONTEXT_INFO()和varchar大小
SELECT username, LEN(username)
FROM users
WHERE id = 1 -- returns: A, 1
到目前为止好。
现在我从另一个表的触发器更新表的用户,使用从CONTEXT_INFO()
值:
set @context = cast('B' as varbinary(128))
set CONTEXT_INFO @context
update some_other_table
set x = 'y'
where id = 97
在触发some_other_table
我做的:
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
的用户名是否正确设置成“B”,但以下现在返回50:
SELECT
username, LEN(username)
FROM
users
WHERE
id = 1 -- returns: B, 50
解决方案在填充上下文时需要:
set @context = cast('B' + replicate(' ', 126) as varbinary(128))
但是,为什么我需要这样做?
当我不垫CONTEXT_INFO
与空间发生了什么,使用它的值更新将导致生成的长度为50(即使我ltrim
和rtrim
更新前的单个字符值)?
为什么我必须把我的CONTEXT_INFO
总共127个字节,而不是128?对于超过127的每一个字符,一个字符从最初设置上CONTEXT_INFO
注意值截断:ANSI_PADDING启用
短铸造值的类型不允许空字节,有没有简单的方法来删除所有尾随NULL字节? –
如果你从一个128字节的空填充'CONTEXT_INFO'中选择50个字节,那么你希望有什么作为填充而不是'NULL'?如果你不想填充,那么只需选择确切的长度。 –
但我怎么知道有多少非NULL字符传递到CONTEXT_INFO?在我的示例中,传递的值是硬编码的,但在实时代码中,CONTEXT_INFO使用动态数据填充。 –