在我的电子商务门户网站中,我收到了来自经销商的产品EAN代码。我想完成计算checksum digit的EAN-12代码,然后返回EAN-13。
从SQL Server表中读取原始代码,并通过存储过程将其复制到另一个SQL Server数据库中。
我想计算现有存储过程中的校验和数字,而不添加其他编程层。用于计算校验和的算法基于数字掩码(它将EAN数字乘以位置权重值,对结果求和,并计算与下一个更大的10倍数的差异)。
很简单,UDF可以实现该算法,但它需要使用临时表来处理数字上的操作,SQL Server不允许在UDF中使用临时表! 你知道有什么工作吗?
算法细节和样本:
EAN-12: 7 2 5 1 8 4 6 6 0 4 0 5
weights: 1 3 1 3 1 3 1 3 1 3 1 3
multip: 7 6 5 3 8 12 6 18 0 12 0 15
sum: 92
checksum: 8 (= 100 - 92)
答案 0 :(得分:1)
您可以在不使用临时表的情况下执行此操作(代码适用于SQL 2008):
CREATE FUNCTION [dbo].[ac_fnEan12ToEan13](@input varchar(12))
RETURNS varchar(13)
AS
BEGIN
declare @weights varchar(12) = '131313131313'
declare @loop int = len(@input)
declare @sum int = 0
while @loop > 0
begin
set @sum = @sum + cast(SUBSTRING(@weights, @loop, 1) as int) * cast(SUBSTRING(@input, @loop, 1) as int)
set @loop = @loop -1
end
return @input + cast((10*ceiling(@sum / 10.0)) - @sum as varchar(1))
END
go
[编辑] 但是如果你想要,你也可以在函数中使用表变量,它们比临时表更有效:
declare @values table (digit int, value int, primary key (digit))
insert @values select 1, 7
答案 1 :(得分:0)
以下函数将根据您的描述计算校验和。它不需要临时表,但它确实使用基于集合的方法来完成任务:
CREATE FUNCTION dbo.GetEAN13CheckSum (@EAN12 varchar(12))
RETURNS int
AS BEGIN
DECLARE @result int;
WITH EAN12_split AS (
SELECT
weight = 3 - number % 2 * 2,
digit = CAST(SUBSTRING(@EAN12, number, 1) AS int)
FROM master..spt_values
WHERE type = 'P'
AND number BETWEEN 1 AND 12
)
SELECT @result = 10 - SUM(weight * digit) % 10
FROM EAN12_split;
RETURN @result;
END
当然,您可以对其进行修改,以便将校验和添加到EAN-12代码中,并将结果作为EAN-13字符串值返回。