sql server mseq:
hello if i have a forula string looks like a '150000*0.9*21/31', how can i covert them to the result 91451.61?
You can also take a look at this: http://users.drew.edu/skass/sql/Infix.sql.txt SK [quoted text, click to view] ricky wrote: >hello, > if i have a forula string looks like a '150000*0.9*21/31', how can i covert them to the result 91451.61?? > thanks in advance!! > >
thanks parkar before, my table looks lik DateInsert StrFormul 2004/01/01 , 150000*0.9*21/3 2004/02/01 , 150000*0.8*21/2 2004/03/01 , 150000*0.87*21/3 After, DateInsert resul 2004/01/01 , 91451.6 2004/02/01 , 9000 2004/03/01 , 88403.2 first of all thanks of ur suggestion. i have a field(StrFormula) in table A and this field contains string("150000*0.9*21/31"),i want to calculate these string at specific time and return results
hi ricky, prefix the string with 'select ' and use EXEC to execute it. Ex: declare @x varchar(50) set @x='150000*0.9*21/31' set @x= 'select ' + @x exec (@x) -- Vishal Parkar vgparkar@yahoo.co.in
Here's another approach that works if the formula is fixed: select x, cast(replace(parsename(x,4),'@','.') as decimal(12,4)) *replace(parsename(x,3),'@','.') *replace(parsename(x,2),'@','.') /replace(parsename(x,1),'@','.') from ( select replace(replace(replace(c1,'.','@'),'*','.'),'/','.') as x from formula ) T SK [quoted text, click to view] Vishal Parkar wrote: >hi ricky, > >if your formula is static ie (number1 * number2 * number3 / number4) then >you can have query as shown in the following example. > >create table formula(c1 varchar(40)) >--sample data >insert into formula >select '150000*0.9*21/31' union all >select '150000*0.8*21/28' union all >select '150000*0.87*21/31' > >--query > >select str(c1 * c2 * c3/c4,10,2)'calc1', c1 * c2 * c3/c4 'calc2' >from >(select cast(left(c1, charindex('*',c1)-1) as decimal(10,2)) c1, >cast(substring (c1, >(charindex('*',c1) + 1), >charindex ('*', c1, charindex('*',c1) + 1) - (charindex('*',c1) + 1)) as >decimal(10,2))c2, >cast(substring (c1, charindex('*',c1,(charindex('*',c1) + 1)) + 1, >(charindex ('/', c1)-1) - charindex('*',c1,(charindex('*',c1) + 1)))as >decimal(10,2)) c3, >cast(right(c1, charindex('/',reverse(c1))-1) as decimal(10,2))c4 >from formula) x > >-- >Vishal Parkar >vgparkar@yahoo.co.in > > > > > > >
thanks steve and vishal but my formula will change day by day, sometimes it will looks like 2004/01/01 , 150000*0.9*21/31 +10 2004/02/01 , 150000*0.8*21/28*(1+8/31)-10 2004/03/01 , 150000*0.87*21/31-100+19
hi ricky, if your formula is static ie (number1 * number2 * number3 / number4) then you can have query as shown in the following example. create table formula(c1 varchar(40)) --sample data insert into formula select '150000*0.9*21/31' union all select '150000*0.8*21/28' union all select '150000*0.87*21/31' --query select str(c1 * c2 * c3/c4,10,2)'calc1', c1 * c2 * c3/c4 'calc2' from (select cast(left(c1, charindex('*',c1)-1) as decimal(10,2)) c1, cast(substring (c1, (charindex('*',c1) + 1), charindex ('*', c1, charindex('*',c1) + 1) - (charindex('*',c1) + 1)) as decimal(10,2))c2, cast(substring (c1, charindex('*',c1,(charindex('*',c1) + 1)) + 1, (charindex ('/', c1)-1) - charindex('*',c1,(charindex('*',c1) + 1)))as decimal(10,2)) c3, cast(right(c1, charindex('/',reverse(c1))-1) as decimal(10,2))c4 from formula) x -- Vishal Parkar vgparkar@yahoo.co.in
Ricky, Then take a look at my first suggestion. Here's a full repro - if you use it, do some careful testing. It doesn't handle absolutely everything, and has limits on expression length, number formats, etc. drop table Ricky drop function InFixVal drop table Sequence0_8000 go -- Keep this table around - it's handy to have! create table Sequence0_8000 ( i int primary key ) insert Sequence0_8000 select top 8001 a*10 + b from ( select top 801 (orderid-10248) as a from northwind..orders order by orderid ) X, ( select top 10 (orderid-10248) as b from northwind..orders order by orderid ) Y order by a*10+b go -- call this with 1 as the second parameter create function InFixVal ( @s varchar(300), @first int ) returns decimal(18,6) as begin if @first = 1 begin set @s = replace(@s,'-','"') end if @s not like '%[+"*/()]%' return @s --If @s is just a number, return it --@s is not just a number, so look for parentheses declare @left int set @left = charindex('(',@s) if @left = 0 begin --no parentheses declare @op int set @op = patindex('%[*/]%',@s) --look for * or / if @op = 0 set @op = patindex('%["+]%',@s) declare @lft int, @rght int set @lft = @op-patindex('%[*/"+]%',reverse(substring(@s,1,@op-1))+'+') set @rght = @op+patindex('%[*/"+]%',substring(@s+'+',@op+1,300)) declare @ys varchar(300) declare @a decimal(18,6), @b decimal(18,6), @y decimal(18,6) set @a = substring(@s,@lft+1,@op-1-@lft) set @b = substring(@s,@op+1,@rght-1-@op) set @y = case substring(@s,@op,1) when '+' then @a+@b when '*' then @a*@b when '/' then @a/@b when '"' then @a-@b end set @ys = case when @lft=0 then '' else substring(@s,1,@lft) end + cast(@y as varchar(30)) + case when @rght > len(@s) then '' else substring(@s,@rght,300) end return dbo.InFixVal(@ys,0) end declare @right int --position of matching right parenthesis set @right = (select top 1 S1.i from Sequence0_8000 S1 join Sequence0_8000 S2 on S1.i >= @left and S2.i <= S1.i and S1.i <= len(@s) and substring(@s,S2.i,1) in ('(',')') group by S1.i having sum(case substring(@s,S2.i,1) when '(' then 1 when ')' then -1 end) = 0 order by S1.i) declare @x decimal(18,6) declare @xs varchar(300) set @xs = substring(@s,@left+1,@right-@left-1) set @x = dbo.InFixVal(@xs,0) set @s = stuff(@s,@left,@right-@left+1,@x) return dbo.InFixVal(@s,0) end go create table Ricky ( d datetime, expression varchar(2000) ) insert into Ricky values ('20040101' , '150000*0.9*21/31 +100') insert into Ricky values ('20040201' , '150000*0.8*21/28*(1+8/31)-100') insert into Ricky values ('20040301' , '150000*0.87*21/31-100+199') select d, dbo.InFixVal(expression, 1), expression from Ricky go [quoted text, click to view] ricky wrote: >thanks steve and vishal, > but my formula will change day by day, sometimes it will looks like >2004/01/01 , 150000*0.9*21/31 +100 >2004/02/01 , 150000*0.8*21/28*(1+8/31)-100 >2004/03/01 , 150000*0.87*21/31-100+199 > > >
hi ricky, in addition to steve's post here is a procedural approach that will make use of dynamic sql. --sample table structure create table formula(idd int identity(1,1),c1 varchar(40)) go --sample data insert into formula select '150000*0.9*21/31 +100' union all select '150000*0.8*21/28*(1+8/31)-100' union all select '150000*0.87*21/31-100+199' go --stored procedure create procedure exec_formulae as begin set nocount on declare @x int, @str nvarchar(150), @c1 varchar(50) declare @t table (idd int, c1 varchar(40), formulae_value decimal(10,2)) declare @y decimal(10,2) set @x = 0 while @x is not null begin select @x=min(idd) from formula where idd > @x select @c1 = c1 from formula where idd = @x set @str = 'select @y=' + @c1 exec sp_executesql @str, N'@y decimal(10,2) output' , @y output if @x is not null insert into @t values(@x, @c1, @y) end select * from @t end go --executing above stored procedure exec exec_formulae -- Vishal Parkar vgparkar@yahoo.co.in
hi parkar when i run your script, and i found that formula looks like idd c 1 200000*0.7 2 200000*0.8 3 200000*0.9 and where's the result?? i guess it must be in stored procedure, how can i make them looks like the following in my formula table idd c1 result 1 200000*0.70 14000 2 200000*0.80 16000 3 200000*0.90 18000
hi ricky, you will have to change the stored procedure on the basis of your table structure.Let me explain you this stored procedure. [quoted text, click to view] >>declare @t table (idd int, c1 varchar(40), results decimal(10,2))<<
above variable @t of type table will return the resultset which will hold the value of column idd=primary key/unique key value. column c1=formula text column results=output of formula you can change this table structure on the basis of output that you require from stored procedure. [quoted text, click to view] >>while @x is not null
begin select @x=min(idd) from formula where idd > @x<< above loop will iterate through each and every row of the table "formula". assuming idd as a primary key of the table. you will have to replace this table name with yours, and the primary key/unique key column in the table. [quoted text, click to view] >>select @c1 = c1 from formula where idd = @x<<
above select statement will pass the value of "formula string" that need to be calculated, to the variable @c1, (replace this column name with the "formula column" that you have).Also note that @x is the key value of each row, that will be passed to this variable, each time loop iteration occurs. [quoted text, click to view] >>set @str = 'select @y=' + @c1
exec sp_executesql @str, N'@y decimal(10,2) output' , @y output<< above statement gets processed and output of formula is passed to the variable @y, there shouldn't be any change here if correct value is passed to the @c1 variable. [quoted text, click to view] >>insert into @t values(@x, @c1, @y)<<
finally each row's fomula column and the calculation of the formula value gets inserted into @t table. -- Vishal Parkar vgparkar@yahoo.co.in
hi vishal when i run this script under query analyzer, everything is ok. but i run these under asp code and it's doesn't work....
hi ricky, once you create stored procedure it gets created in the database. No need to run the "create procedure...." statement again, all you have to do is execute stored procedure through "asp". You will have to look for exact syntax which will execute the stored procedure. you can also take help of newsgroups like "microsoft.public.vb" whereby you will get ample of help about executing "stored procedure" through aps/vb code. -- Vishal Parkar vgparkar@yahoo.co.in
Don't see what you're looking for? Try a search.
|