最近做的一个项目,需要一个触发器来算CRC值,在做触发器的过程中遇到了几个问题,最主要的就是image变char,3天的研究,总算把它写出来了,不容易呀。。:-)
现在我就把解决的方法写出来。先是触发器的实现:
ALTER TRIGGER [T_app]
ON [dbo].[tb_softwareInfo_application]
AFTER INSERT,UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
--declare @str varchar(8000)
--set @s = '0x312C33343232303330392E53474E2C303035312C4372656469742C312C312C353832462C30303041363538342C30303036343035332C39333030302C30303030303030302C323030303030'
--select @s=FileData from dbo.tb_softwareInfo_application as t where t.ID =96
--exec prc_HexToStr @s,@str output
update tb_softwareInfo_application set Crc = dbo. ucCalcLRC(FileData,datalength(FileData)),Leng = DataLength(FileData)
END
ucCalcLRC这是算触发器的function,里面还有些测试的数据,下面就是ucCalcLRC方法:
ALTER FUNCTION [dbo].[ucCalcLRC]
(
@p_ucData image,
@i_Length int
)
RETURNS int
AS
BEGIN
declare @uc_LRC int
declare @i int
set @i = 1
set @uc_LRC = 0
while @i<=@i_Length
begin
declare @str varchar(8000)
set @str= dbo.HexToStr(@p_ucData,@i)
declare @iLoop int
set @iLoop = 1
while @iLoop<=len(@str)
begin
set @uc_LRC = @uc_LRC^ASCII(substring(@str,@iLoop,1))
set @iLoop=@iLoop+1
end
set @i=@i+8000
end
return @uc_LRC
END
HexToStr这就是image转char的function,其中由于varchar的最大值只有8000,所以用了一个循环来解决长度不够的问题,里面的循环是算CRC的算法。下面是HexToStr方法:
ALTER function [dbo].[HexToStr]
(
@source image ,
@length int
)
returns varchar(8000)
as
begin
declare @len int,@sql nvarchar(100) ,@str varchar(8000)
--set @len=datalength(@source)/2
declare @c varbinary(8000)
set @c=substring(@source,@length,@length+8000)
set @str=cast(@c as varchar(8000))
return @str
end
转换的关键就是先用binary保存image文件再用cast()方法转换成char。