PANTHEON™ Помош

 Категории
[Collapse]АРЕС
  Овозможување прика со волшебник во персонални мапи
 Главна страна - Добре дојдовте во помош за PANTHEON
[Collapse]PANTHEON
 [Collapse]PANTHEON упатства
  [Expand]Водич за Datalab PANTHEON™
  [Expand]Водич за PANTHEON Ретал
  [Expand]Водич за PANTHEON Вет
  [Expand]Водич за PANTHEON Farming
 [Collapse]PANTHEON кориснички прирачници
  [Collapse]Кориснички прирачник Datalab PANTHEON™
   [Collapse]Како да започнете?
    [Expand]Бизнис Енциклопедија
     Први чекори во PANTHEON
    [Expand]Инсталација на PANTHEON и потребните компоненти
    [Expand]Основни концепти и упатства за работа со PANTHEON
    [Collapse]PANTHEON Систем
     [Expand]PANTHEON Системски податоци
     [Expand]Microsoft SQL сервер
     [Expand]Мајкрософт Виндоус Утилити
     [Expand]Безбедносна политика
     [Collapse]Администрација на бази
       Converting Posts to a Different Currency
       ФормулаПарсер
      [Expand]Performance Tweaking
    [Expand]PANTHEON Безбедност
    [Expand]Пример на употреба на PANTHEON во замислено Претпријатие
    [Expand]Често поставувани прашања за PANTHEON
    [Expand]Архива - Како да започнете
   [Expand]еРаботење
   [Expand]Подесувања
   [Expand]Нарачки
   [Expand]Материјално
   [Expand]Производство
   [Expand]Сервис
   [Expand]Помош
   [Expand]Кадри
   [Expand]Финансии
   [Expand]ЗЕУС Деловен аналитички систем
    Персонал
    Ценовник
    Договор за лиценца на крајниот корисник
  [Expand]Корисничко упатство за PANTHEON Ретал
  [Expand]Корисничко упатство за PANTHEON Vet
  [Expand]Корисничко упатство за ПАНТЕОН Земјоделство
[Collapse]PANTHEON Web
   
 [Collapse]Водич за PANTHEON Web
  [Expand]Водич за PANTHEON Web Light
  [Expand]Водич за PANTHEON Web Terminal
  [Expand]Водич за PANTHEON Web Legal
 [Collapse]Кориснички прирачник за PANTHEON Web
  [Expand]Како да започнете со PANTHEON Web
  [Expand]Кориснички прирачник за PANTHEON Web Light
  [Expand]Кориснички прирачник за PANTHEON Web Terminal
  [Expand]Кориснички прирачник за PANTHEON Web Legal
[Collapse]PANTHEON Гранула
 [Collapse]Водич за PANTHEON Гранули
  [Expand]Гранула Кадри
  [Expand]Гранула Патни налози
  [Expand]Гранула Документи и задачи
  [Expand]Гранула Контролна табла
  [Expand]Гранула B2B нарачки
  [Expand]Гранула Сервис на терен
  [Expand]Гранула Инвентар на основни средства
  [Expand]Гранула Попис на магацини
 [Collapse]Кориснички прирачник за PANTHEON Гранули
  [Expand]Започнување, Pantheon гранули
  [Expand]Гранула Кадри
  [Expand]Гранула Патни налози
  [Expand]Гранула Документи и Задачи
  [Expand]Гранула Б2Б нарачки
  [Expand]Гранула Контролна табла
  [Expand]Гранула Сервис на терен
  [Expand]Инвентаризација на фиксни средства
  [Expand]Гранула Попис на магацин
[Expand]Кориснички сервер

Load Time: 1515,6532 ms
"
  2709 | 3106 | 437763 | AI translated
Label

FormulaParser

FormulaParser

FormulaParser

Овој пример не е толку поврзан со SQL-InterActive туку повеќе со начинот на програмирање T-SQLa. Пошто знаеме колку се програмските примери вредни, го вклучивме во упатствата.

Примерот добро илустрира рекурзии, складирани процедури. Главната процедура е наменета за израчунување математички изрази, кои ги внесуваме во форма на низи алфанумерички знаци.

Процедурите се направени така, што ако го отстраниме --!! пред print командите, го гледаме текот на извршувањето и рекурзиите.

Помошна процедура, која враќа аргументи

create procedure [dbo].[dl_PA_ParserGetArg]
  @sExpression varchar(8000),
  @lLeft bit,
  @iOperand int,
  @iLimit integer output,
  @mResult float output,
  @sEr varchar(8000) output

-- тест параметри
-- декларирај
--   @sExpression varchar(8000),
--   @lLeft bit,
--   @iOperand int,
--   @iLimit integer,
--   @mResult money,
--   @sEr varchar(8000)
-- 
-- set @sExpression='2*3'
-- set @lLeft=1
-- set @iOperand=2
-- exec dl_PA_GetArg @sExpression, @lLeft, @iOperand, @iLimit output,@mResult output, @sEr output
--  --!! print '-----'
--  --!! print @iLimit 
--  --!! print cast(@mResult as char)
--  --!! print @sEr

as

declare
  @sTempArg varchar(8000)

set nocount on
set @sTempArg = ' '+@sExpression+' '  -- ова е само за да се справи со ограничувањата во циклусот (да не добиеме j[0])
set @iOperand = @iOperand + 1
--!! print '    @sTempArg='+@sTempArg+'#'
--!! print '    @iOperand=' + Str(@iOperand) + '#' + SubString(@sTempArg,@iOperand,1) 
if @lLeft=1
  begin  -- лев аргумент
   set @iLimit = @iOperand - 1
   --!! print '      лев аргумент'
   --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
   while (@iLimit > 0) and not (SubString(@sTempArg,@iLimit,1) in ('+','-','/','*','\','|'))
     set @iLimit = @iLimit-1
   -- да провериме за водечки "-" за лев аргумент.
   if @iLimit > 1 
     if SubString(@sTempArg,@iLimit,1) = '-'
        set @iLimit = @iLimit-1
   --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
   --!! print '      @iLimitg='+cast(@iLimit as varchar)
   set @sTempArg = SubString(@sTempArg,@iLimit+1,@iOperand-@iLimit-1)
   --!! print '      излез лев @sTempArg='+@sTempArg
  end
else
  begin  -- десен аргумент
    set @iLimit = @iOperand + 1
    --!! print '      десен аргумент'
    --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
    set @iLimit = @iLimit+1
    --!! print '      Извештавање...'
    while (@iLimit <= Len(@sTempArg)) and not (SubString(@sTempArg,@iLimit,1) in ('+','-','/','*','\','|'))
      set @iLimit = @iLimit+1
    --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
    set @sTempArg = SubString(@sTempArg,@iOperand+1,@iLimit-@iOperand-1)
    --!! print '    излез десен @sTempArg='+@sTempArg
  end
if @sTempArg = '' 
  begin
    if SubString(@sExpression,@iOperand,1) in ('+','-')  -- ова е за -x / +x обработка
      set @mResult = 0
    else
      set @sEr = 'Невалидна употреба на оператори во '+@sExpression
  end
else
  begin
    --!! print '    излез @sTempArg='+@sTempArg
    set @mResult = Convert(float,@sTempArg,2)
    --!! print '    излез @mResult='+Str(@mResult,35,15)
    -- !! проверете за грешка тука !! Обработка на исклучоци !!
    --    if code <> 0 then
    --      er = @sExpression+'не е број!'
    --    else
    --      begin
    set @iLimit = @iLimit - 1
    --      end
  end

Главна процедура, која израчунува израз

create procedure [dbo].[dl_PA_ParseAritNew]
  @sExpression varchar(8000),
  @rResult float output,
  @sEr varchar(8000) output -- @sEr = ''<- без грешка, @sEr <> '' <- грешка во изразот

-- Внимание ! ---
-- Функцијата секогаш повикај како ParseArit(0,израз,'+',er) !!!!!
-- Во изразот не смее да има празни места "2+3" = ОК / "2 + 3" <> ОК !!!!
-- Во изразот не смее да има небалансирани загради (погледни тест 2)!
-- (c) А. Мертелј, 1997, 2002

as

declare
  @iBrackets int,       -- броење на загради ()
  @i int,               -- броење 1
  @j int,               -- броење 2
  @iLen int,            -- должина на @sExpression 
  @iLeftLimit int,      -- лев ограничувач
  @iRightLimit int,     -- десен ограничувач
  @rLeft float,         -- вредност на лев аргумент
  @rRight float,        -- вредност на десен аргумент
  @lOperatorsExist bit, -- дали имаше оператор во изразот
  @sOrigExpression varchar(8000),
  @sTemp varchar(8000)  -- временска променлива

set nocount on  

set @iLen = Len(@sExpression)
set @sOrigExpression = @sExpression
-- исправи "+x" во "x"
if SubString(@sExpression,1,1) = '+'
  set @sExpression = Right(@sExpression,@iLen-1)
-- исправи "--x" во "x"
set @sExpression = Replace(@sExpression,'--','')
--!! print 'во функцијата exp = ' +@sOrigExpression
if @sEr = '' 
  begin   -- без грешка на влез
    set @lOperatorsExist = 0
    -- обработка на загради ()
    set  @i = Charindex('(',@sExpression)
    if @i > 0 -- @i > 0?
      begin -- има (,)
        --!! print '  -- има загради'
        set @lOperatorsExist = 1
        set @iBrackets = 1
        set @j = @i + 1  
        while (@j <= @iLen) and (@iBrackets > 0) -- најди прво совпаѓање
          begin
            if SubString(@sExpression,@j,1) = ')'
              set @iBrackets = @iBrackets-1
            if SubString(@sExpression,@j,1) = '('
              set @iBrackets = @iBrackets+1
            set @j = @j + 1
          end
        set @sTemp = SubString(@sExpression,@i+1,@j-@i-2)
        -- израчунај надворешна пар
        exec dl_PA_ParseAritNew @sTemp,@rResult output,@sEr output 
        --!! print '    ()@rResult='+Str(@rResult,25,10)
        set @sTemp = LTrim(Str(@rResult,35,15))
        --!! print '    ()@sTemp='+@sTemp
        set @sTemp = Replace(@sTemp,',','.')  -- промени можен ',' во '.'
        --!! print '    ()@sTemp, по замена ='+@sTemp
        -- замени надворешна пар со резултат
        set @sExpression = SubString(@sExpression,1,@i-1)+@sTemp+SubString(@sExpression,@j,@iLen-@j+1)  
        --!! print '    ()@sExpression=' + @sExpression 
      end -- има (,)
    else  -- @i > 0? не, нема (,)
      begin -- провери за *,/
        set @i = 1
        while not (SubString(@sExpression,@i,1) in ('*','/')) and (@i < @iLen) 
          set @i = @i + 1
        if SubString(@sExpression,@i,1) in ('*','/') 
          begin  -- *,/ најдено
            --!! print '  -- има *,/  најдено на позиција ' + Str(@i)
            set @lOperatorsExist = 1
            exec dl_PA_ParserGetArg @sExpression,1,@i,@iLeftLimit output,@rLeft output,@sEr output
            exec dl_PA_ParserGetArg @sExpression,0,@i,@iRightLimit output,@rRight output,@sEr output
            --!! print '    */@rLeft='+Str(@rLeft,25,15)
            --!! print '    */@rRight='+Str(@rRight,25,15)
            --!! print '    */@sEr='+@sEr
            if @sEr = '' 
              begin
                if SubString(@sExpression,@i,1) = '*' 
                  set  @rResult = @rLeft*@rRight
                else
                  if SubString(@sExpression,@i,1) = '/'
                    exec dl_DivT @rLeft,@rRight,@rResult output
                set @sTemp = LTrim(Str(@rResult,35,15))
                --!! print '    */@rResult='+Str(@rResult,25,10)
                --!! print '    */@sTemp='+@sTemp
                set @sTemp = Replace(@sTemp,',','.')  -- промени можен ',' во '.'
                --!! print '    */@sTemp, по замена ='+@sTemp
                --!! print '    */Десен дел=#'+ SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1) + '#'
                -- замени *,/ со резултат
                if @iLeftLimit > 0
                   set @sExpression = SubString(@sExpression,1,@iLeftLimit) + @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                else
                   set @sExpression = @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
		--!! print '    */@sExpression(Финално)=' + @sExpression 
              end
          end  -- *,/ најдено
        else
          begin -- провери за делење, мод
            set @i = 1
            while not (SubString(@sExpression,@i,1) in ('\','|')) and (@i < @iLen)
              set @i = @i + 1
            if SubString(@sExpression,@i,1) in ('\','|')
              begin  -- дел, мод најдено
                --!! print '  -- има \,| (дел,мод)  најдено на позиција ' + Str(@i)
                set @lOperatorsExist = 1
                exec dl_PA_ParserGetArg @sExpression,1,@i,@iLeftLimit output,@rLeft output,@sEr output
                exec dl_PA_ParserGetArg @sExpression,0,@i,@iRightLimit output,@rRight output,@sEr output
                --!! print '    \,|@rLeft='+Str(@rLeft,25,15)
                --!! print '    \,|@rRight='+Str(@rRight,25,15)
                --!! print '    \,|@sEr='+@sEr
                if @sEr = ''
                  begin
                    if SubString(@sExpression,@i,1) = '\'
                      begin
                        if @rRight <> 0
                          set @rResult = cast((@rLeft / @rRight + 0.0) as int)
                        else
                          set @rResult = 0
                      end
                    else
                      if SubString(@sExpression,@i,1) = '|'
                        begin
                          if @rRight <> 0
                            set @rResult = cast(@rLeft as int) % cast(@rRight as int)
                          else
                            set @rResult = 0
                        end
                    set @sTemp = LTrim(Str(@rResult,35,15))
                    set @sTemp = Replace(@sTemp,',','.')  -- промени можен ',' во '.'
                    -- замени дел, мод со резултат
                    if @iLeftLimit > 0
                      set @sExpression = SubString(@sExpression,1,@iLeftLimit) + @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                    else
                      set @sExpression = @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                  end
              end  -- дел, мод најдено
            else
              begin -- провери за збир и разлика
                set @i = 1
                if SubString(@sExpression,@i,1) = '-'
                  set @i = @i + 1
                while not (SubString(@sExpression,@i,1) in ('+','-'))  and (@i < @iLen)
                  set @i = @i + 1
                --!! print '    +,- @i='+cast(@i as varchar)
                if SubString(@sExpression,@i,1) in ('+','-')
                  begin  -- +,- најдено  
                    --!! print '  -- има +,-  најдено на позиција ' + Str(@i)
                    set @lOperatorsExist = 1
                    exec dl_PA_ParserGetArg @sExpression,1,@i,@iLeftLimit output,@rLeft output,@sEr output
                    exec dl_PA_ParserGetArg @sExpression,0,@i,@iRightLimit output,@rRight output,@sEr output
                    --!! print '    +,- @rLeft='+Str(@rLeft,25,15)
                    --!! print '    +,- @rRight='+Str(@rRight,25,15)
                    --!! print '    +,- @sEr='+@sEr
                    if SubString(@sExpression,@i,1) = '+'
                       set @rResult = @rLeft + @rRight
                    else
                      if SubString(@sExpression,@i,1) = '-'
                        set @rResult = @rLeft - @rRight
                    set @sTemp = LTrim(Str(@rResult,35,15))
                    --!! print '    +-@rResult='+Str(@rResult,25,10)
                    --!! print '    +-@sTemp='+@sTemp
                    set @sTemp = Replace(@sTemp,',','.')  -- промени можен ',' во '.'
                    --!! print '    +-@sTemp, по замена ='+@sTemp
                    -- замени +,- со резултат
                    if @iLeftLimit > 0
                      set @sExpression = SubString(@sExpression,1,@iLeftLimit) + @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                    else
                      set @sExpression = @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                    --!! print '    +-@sExpression=' + @sExpression 
                  end -- +,- најдено
              end  -- провери за збир и разлика
          end  -- провери за делење, мод
        end  -- провери за множење, делење
    if @sEr = ''
      begin  -- без грешка до сега
        if @lOperatorsExist = 1
          begin
            --!! print '  излез за рекурзија оригинал. @sExpression='+@sExpression+' @sExpression=' + @sExpression
            exec dl_PA_ParseAritNew @sExpression,@rResult output,@sEr output -- парсирај со вредност
          end
        else
          begin
            --!! print '  излез за оригинал. @sExpression='+@sExpression+' @sExpression=' + @sExpression
            set @rResult = Convert(float,@sExpression,2)
          end
      end -- без грешка до сега
  end -- без грешка на влез

Тестни примери

-- тест случај 1
 declare
   @sExpression varchar(8000),
   @mResult money,
   @sEr varchar(8000)
 set @sExpression='2*3'
 set @sEr = ''
 --!! print @sExpression
 exec dl_PA_ParseAritNew @sExpression, @mResult output,@sEr output
 --!! print '-----'
 --!! print Str(@mResult,35,15)
 --!! print @sEr
--тест случај 2
 create table _TEST_PARSER
 (
    FORMULA varchar(300),
    TEST money,
    ER varchar(500),
    REZULTAT money
 )
 declare
    @sExpression varchar(8000),
    @mTest float,
    @mResult float,
    @i int,
    @iBrackets int,
    @sEr varchar(8000)
  set nocount on 
  declare crKurzor cursor local fast_forward for 
    select FORMULA,TEST
      from _TEST_PARSER
  open crKurzor
  fetch next from crKurzor into @sExpression,@mTest
  while @@fetch_status = 0 
  while @@fetch_status = 0 
    begin
      -- провери за баланс на загради
      print '--------------------------------------------------------'
      print ' Тестирање: ' + @sExpression
      print ' Очекуван резултат = ' + Str(@mTest)
      set @i = 1  
      set @iBrackets = 0
      while (@i <= Len(@sExpression))  -- провери цел израз
        begin
          if SubString(@sExpression,@i,1) = ')'
            set @iBrackets = @iBrackets-1
          if SubString(@sExpression,@i,1) = '('
            set @iBrackets = @iBrackets+1
          set @i = @i + 1
        end
      if @iBrackets <> 0
        set @sEr = 'Небалансирани загради во ' + @sExpression
      else
        begin
          set @sEr = ''
          exec dl_PA_ParseAritNew @sExpression, @mResult output,@sEr output
        end
      print ' Израчунат резултат = ' + Str(@mResult)
      if (@mResult = @mTest)
        print ' ОК'
      else
        print ' Грешка (@mResult - @mTest) = ' + Str(@mResult - @mTest)
      print '--------------------------------------------------------'
      update _TEST_PARSER
        set REZULTAT = @mResult,
            ER = @sEr
        where LTrim(RTrim(FORMULA)) = LTrim(RTrim(@sExpression))
      fetch next from crKurzor into @sExpression,@mTest
    end
  close crKurzor
  deallocate crKurzor
  select LTrim(RTrim(FORMULA)) as 'Formula',TEST,REZULTAT,LTrim(RTrim(ER)) as 'ErrorMsg'
    from _TEST_PARSER
      where (TEST <> REZULTAT) or (TEST is null)

 

Rate this topic
Was this topic usefull?
Comments
Comment will also bo visible in forum!