具体要求是这样的,现在要计算一些指标,但是指标的计算公式的表达式是不固定的,例如表达式可能是A-B+C, 也可能是(A*B)-(C/D),也可能是A-(B-C),也就是符号不固定,操作符也不固定,操作符,象A,B,C这些操作符还是从数据库中的字段获得的,我想做一个录入的界面来保存这些由用户生成的表达式,我该如何设计呢,我想了很久也没有思路,希望大家多多指教啊!

解决方案 »

  1.   


    楼主可以这样,设计两个表,一个用来存储字段的值,另外一个用来存储表达式。如下
    create table test(name varchar(12),value int)
    insert into test values('aa',12)
    insert into test values('bb',13)
    insert into test values('cc',14)create table temp(code varchar(30))
    insert into temp values('aa+bb+cc'  )
    insert into temp values('aa+(bb*cc)')
    gocreate proc wsp
    as
    declare @code varchar(30),@sql varchar(8000)
    declare tc cursor for select code from temp
    open tc
    fetch next from tc into @code
    while @@fetch_status=0
    begin
        set @sql=''
        select @sql=isnull(@sql+',','')+'['+name+']=max(case name when '''+name+''' then value end)' from test
        set @sql='select '+@code+' from (select '+stuff(@sql,1,1,'')+' from test) t' 
        exec(@sql)
        fetch next from tc into @code
    end
    close tc
    deallocate tc调用存储过程exec wsp
    可以得到结果如下:39
                    194
      

  2.   


    另外楼主也可以将字段和表达式也这样的方式存储:
    create  table t(id int,a int,b int,c int)
    insert into t(id,a,b) select 1,2,3
    insert into t(id,a,b) select 2,4,3create  table h(id int,val varchar(10))
    insert into h select 1,'a+b'
    insert into h select 2,'a*b'create proc wsp
    @id int
    as
    declare @sql varchar(1000)
    select @sql='update t set c =' + val from h where id = @id 
    set @sql=@sql +' where id='+cast(@id as varchar)
    exec(@sql)exec wsp 1
      

  3.   

    放入hashtable就成了hashtable ht=new hashtable()
    ht.add("A",1)
    ht.add("B",2)//A+B做一下替换就可以了Convert.toint(ht["A"])+conver.toint(ht["B"])另外也有用 codedom动态编译的,还有用jscript引擎的Eval()函数,你自己查查看把
      

  4.   

    还有一种,就是把数据放到js里在客户端计算,因为js里直接有把字符当命令执行的函数eval()
    js
    <script>
    var a=<%=a%>
    var b=<%=b%>
    alert(eval("a+b"))
    </script>
      

  5.   

    顶,用js的eval可以在客户端实现,用sql可以在数据库里实现
      

  6.   

    这个肯定是要预先定义的你可以放如xml配置里面
    <config>
    <add name="A" fieldName="字段名"/>
    </config>你只要定义A,b,c,d就可以了
    常规的操作符号你可以不管,常规的操作符号+-*/ (), 你可以随便输入,你按我上面说的方法做程序就可以人的到如果是特殊操作符号向微分,积分这样的,比较麻烦你可以要接入mathlib或tex这类的东西做,不过这两个东西有关都是相关的net库,我似乎以前见到过
      

  7.   

    关键看你的表达式有多复杂,例如是否要支持函数,例如sum()、max()之类的。一般而言,两种方案:1.自己写解释器,逐个字符去扫描,词法分析然后语法分析。2.调用CodeDom来帮你把那个给编译了,然后立即执行。
      

  8.   

    private static object Eval(string expression)
        {
            object o;
            System.Data.DataTable table = new System.Data.DataTable();
            System.Data.DataColumn Col = new System.Data.DataColumn("col1", typeof(string), expression);
            table.Columns.Add(Col);        table.Rows.Add(new object[] { "" });
            return o = table.Rows[0][0];
        }
    //复制
    然后调用(我是网页格式所以Response.Write)double a = Convert.ToDouble(Eval(@"1*2+15/3+5"));
    Response.Write(a.ToString());
    //输出的是12
      

  9.   

     我最近也在煩這個,不可以采用腳本來執行、運算這個表達式,因為表達式是根據表達式設計器來組(合)成的,然后把這個表達式寫在數據中,并將表達式中相應的變量在執行時給替換就給搞定了。不過有點煩,就如同cat_hfsz所說的。关键看你的表达式有多复杂,例如是否要支持函数,例如sum()、max()之类的。一般而言,两种方案: 
    1.自己写解释器,逐个字符去扫描,词法分析然后语法分析。 
    2.调用CodeDom来帮你把那个给编译了,然后立即执行。 
      

  10.   


    再此萬分感謝"pt1314917 背着灵魂漫步 "先生的兩個SQL代碼,讓我受益匪淺呀謝謝
      
      

  11.   


    如果要支持函数,例如sum()、max()之类的,都可以用此方法,因為SQLSERVER本身提供了很多數學函數,感覺中哈!
      

  12.   


    至于LZ想問的問題就相當的簡單了哈,你可以參照SQLSERVER中或者EXCEL中再或者MSFOXPRO的表達式、公式之類的設計器,可以照它那個界面做,不知道我理解的是否正確(對于你的提問)。