• When I ran Ben's code, I had some problems if I didn't leave spaces between the operators and the values. i.e., fn_simplemath('3 - 4') worked while fn_simplemath('3-4') failed... I suspect this would require a minor tweaking of some of the substring arguments. But trying to debug a recursive function can be a bit troublesome.

    It also occurred to me that since were were not concerned with operator precedence and simply calculating from left to right, we should be able to simply loop through the string without needing to be recursive.

    My approach was to create a string that duplicates the input except for replacing all the "acceptable" operator values with a single unique character, in my case I used a tilde(~). This second string can then be used to identify the position of all the operators in the original string and make it easier to parse out the individual operand values

    Here is my code:

    CREATE Function [dbo].[fn_simplemath2]

    ( @Expression1 varchar(255))

    returns numeric(18,6)

    As

    BEGIN

    --

    -- @Expression2 will duplicate @Expression1 with all operators replaced with ~

    Declare @Expression2 varchar(255)

    Set @Expression2 =

    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@Expression1,'-','~'),'+','~'),'*','~'),'/','~'),'%','~')

    --

    -- Local variables

    Declare @PrevOpLoc int -- Location of previous operator

    Declare @NextOpLoc int -- Location of next operator

    Declare @OpChar Char(1) -- Current operator character

    Declare @Result numeric(18,6) -- Hold running calculation and final return value

    Declare @NextVal numeric(18,6) -- the next substring value to be used to modify result base on operator

    --

    -- Find the first operator

    Set @NextOpLoc = CHARINDEX('~',@Expression2)

    --

    -- Initialize @Result to the first substring, If there are no operators, move entire string to @Result

    Set @Result =

    CASE

    When @NextOpLoc = 0 then CAST(@Expression1 as numeric(18,6))

    Else CAST(LEFT(@Expression1,@NextOpLoc-1) as numeric(18,6))

    END

    --

    -- Now we will loop until we run out of operators

    While @NextOpLoc <> 0

    BEGIN

    -- Get the actual operator from @Expression1, pull out the next substring value

    Set @OpChar = SUBSTRING(@Expression1,@NextOpLoc,1)

    Set @PrevOpLoc = @NextOpLoc

    Set @NextOpLoc = CHARINDEX('~',@Expression2, @NextOpLoc + 1)

    Set @NextVal= Cast(

    SUBSTRING(@Expression1,@PrevOpLoc+1,

    Case

    When @NextOpLoc = 0 then LEN(@Expression1)

    Else @NextOpLoc-1

    End

    - @PrevOpLoc) as numeric(18,6))

    --

    -- Perform the appropriate operation

    Set @Result =

    Case @OpChar

    When '-' then @Result - @NextVal

    When '+' then @Result + @NextVal

    When '*' then @Result * @NextVal

    When '/' then @Result / @NextVal

    When '%' then @Result % @NextVal

    Else null

    End

    END

    Return @Result

    END