从 varchar 转换为 varbinary 并转换回来的奇怪结果 -- sql server 2008
Weird result coverting from varchar to varbinary and converting back -- sql server 2008
存储过程如下:
CREATE PROCEDURE dbo.TestTestTest AS
BEGIN
DECLARE @ProcedureIdForTracking varbinary(128) = CONVERT(varbinary(128), @@procid)
DECLARE @ProcedureNameForTracking varbinary(128) = CONVERT(varbinary(128), OBJECT_NAME(@@procid))
SELECT @@procid AS originalProcid, @ProcedureIdForTracking, CONVERT(bigint, @ProcedureIdForTracking) AS ConvertBackId
SELECT OBJECT_NAME(@@procid) AS originalName, @ProcedureNameForTracking, CONVERT(varchar(1000),
@ProcedureNameForTracking) AS ConvertBackName
SET CONTEXT_INFO @ProcedureNameForTracking
END
我可以从转换中恢复@@procid,但不能恢复存储过程名称。有什么想法吗?OBJECT_NAME 函数有什么问题吗?
结果:
对象名称的数据类型为 SYSNAME
(NVARCHAR(128)
的同义词),因此您正在从一种数据类型转换为二进制数据类型,然后再转换回另一种数据类型,因此您没有进行相反的操作。您可以相当简单地证明这一点:
DECLARE @ProcName SYSNAME = 'dbo.TestTestTest'
DECLARE @VarBin VARBINARY(128) = CONVERT(VARBINARY(128), @Procname);
SELECT Inccorect = CONVERT(VARCHAR(1000), @VarBin),
Correct = CONVERT(NVARCHAR(128), @VarBin);
产生:
Inccorect Correct
------------------------------
d dbo.TestTestTest
此外,NVARCHAR
每个字符需要2个字节,所以VARBINARY(128)
不够长,无法存储,再次证明:
DECLARE @ProcName SYSNAME = REPLICATE('|', 128);
DECLARE @VarBin VARBINARY(128) = CONVERT(VARBINARY(128), @Procname);
SELECT Len1 = LEN(@ProcName),
Len2 = LEN(CONVERT(NVARCHAR(128), @VarBin));
给出:
Len1 Len2
-----------------
128 64
因此您需要调整类型和长度:
DECLARE @ProcedureIdForTracking varbinary(128) = CONVERT(varbinary(128), @@procid)
DECLARE @ProcedureNameForTracking varbinary(256) = CONVERT(varbinary(128), OBJECT_NAME(@@procid))
SELECT @@procid AS originalProcid, @ProcedureIdForTracking, CONVERT(bigint, @ProcedureIdForTracking) AS ConvertBackId
SELECT OBJECT_NAME(@@procid) AS originalName, @ProcedureNameForTracking, CONVERT(nvarchar(128),
@ProcedureNameForTracking) AS ConvertBackName
SET CONTEXT_INFO @ProcedureNameForTracking
存储过程如下:
CREATE PROCEDURE dbo.TestTestTest AS
BEGIN
DECLARE @ProcedureIdForTracking varbinary(128) = CONVERT(varbinary(128), @@procid)
DECLARE @ProcedureNameForTracking varbinary(128) = CONVERT(varbinary(128), OBJECT_NAME(@@procid))
SELECT @@procid AS originalProcid, @ProcedureIdForTracking, CONVERT(bigint, @ProcedureIdForTracking) AS ConvertBackId
SELECT OBJECT_NAME(@@procid) AS originalName, @ProcedureNameForTracking, CONVERT(varchar(1000),
@ProcedureNameForTracking) AS ConvertBackName
SET CONTEXT_INFO @ProcedureNameForTracking
END
我可以从转换中恢复@@procid,但不能恢复存储过程名称。有什么想法吗?OBJECT_NAME 函数有什么问题吗?
结果:
对象名称的数据类型为 SYSNAME
(NVARCHAR(128)
的同义词),因此您正在从一种数据类型转换为二进制数据类型,然后再转换回另一种数据类型,因此您没有进行相反的操作。您可以相当简单地证明这一点:
DECLARE @ProcName SYSNAME = 'dbo.TestTestTest'
DECLARE @VarBin VARBINARY(128) = CONVERT(VARBINARY(128), @Procname);
SELECT Inccorect = CONVERT(VARCHAR(1000), @VarBin),
Correct = CONVERT(NVARCHAR(128), @VarBin);
产生:
Inccorect Correct
------------------------------
d dbo.TestTestTest
此外,NVARCHAR
每个字符需要2个字节,所以VARBINARY(128)
不够长,无法存储,再次证明:
DECLARE @ProcName SYSNAME = REPLICATE('|', 128);
DECLARE @VarBin VARBINARY(128) = CONVERT(VARBINARY(128), @Procname);
SELECT Len1 = LEN(@ProcName),
Len2 = LEN(CONVERT(NVARCHAR(128), @VarBin));
给出:
Len1 Len2
-----------------
128 64
因此您需要调整类型和长度:
DECLARE @ProcedureIdForTracking varbinary(128) = CONVERT(varbinary(128), @@procid)
DECLARE @ProcedureNameForTracking varbinary(256) = CONVERT(varbinary(128), OBJECT_NAME(@@procid))
SELECT @@procid AS originalProcid, @ProcedureIdForTracking, CONVERT(bigint, @ProcedureIdForTracking) AS ConvertBackId
SELECT OBJECT_NAME(@@procid) AS originalName, @ProcedureNameForTracking, CONVERT(nvarchar(128),
@ProcedureNameForTracking) AS ConvertBackName
SET CONTEXT_INFO @ProcedureNameForTracking