Структура таблицы Sql Server внутри пользовательской функции - PullRequest
0 голосов
/ 09 марта 2012

На моем портале электронной коммерции я получаю EAN-коды продуктов от дистрибьюторов.Я хочу завершить коды 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)

Ответы [ 2 ]

1 голос
/ 09 марта 2012

Вы можете сделать это, не используя временную таблицу (код для 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

[Edit] Но если вы хотите, вы можете использовать переменные таблицы и в функциях, они болееэффективнее, чем временные таблицы:

    declare @values table (digit int, value int, primary key (digit))
    insert @values select 1, 7
0 голосов
/ 09 марта 2012

Следующая функция рассчитает контрольную сумму в соответствии с вашим описанием.Для этого не требуется временная таблица, хотя для выполнения задачи используется подход на основе множеств:

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.

...