2016-06-13 58 views
0

我试图以这样一种方式构建查询,即我的同事可以修改如何计算不同成本要素。查询的简化版本如下:从用户输入构建SQL查询

SELECT 
    ProductWeight * ShippingCost As Shipping, 
    ExpectedRevenue * GRTRate * As GRT 
FROM PriceTable 

我想允许用户控制如何运输和GRT计算,所以我创建公式的第二个表:

State | Component | Formula 
______________________________________________ 
NJ | Shipping | 'ProductWeight * ShippingCost' 
NY | GRT  | 'ExpectedRevenue * GRTRate' 

用户就能够通过Access前端中的表单修改这些公式。理想情况下,我想加入PriceTable和产品和状态公式并评估公式,但我还没有找到任何方法来完成这项工作,而AFAIK SQL实际上并非如此。

目前的解决方法,我有:

基于一些答案我在这里看到关于建立动态查询,我使用的XML路径方法来创建公式的列表,像这样:

Declare @formulas As nvarchar(max) 
Set @formulas = (
    SELECT DISTINCT Formula + ' As ' + Component + ',' As [text()] 
    FROM Formulas 
    For XML Path('') 
) 
Set @formulas = LEFT(@formulas, len(@Formulas)-1) 

然后,我创建了一个使用该公式建立查询一个变量:

Declare @query As nvarchar(max) 
@query = 'SELECT ' + @formulas + ' FROM PriceTable;' 

虽然这跑,我不能APPL y在不同州销售的产品的不同公式。无论状态如何,这只会为每个产品返回一个公式。即使有一堆条件逻辑,它看起来也很笨重。有没有更好的方法来处理这种情况?

回答

1

首先要非常小心地接受用户输入并建立动态查询!这是一个相当大的安全风险,请阅读SQL注入等。

其次,您可以使用列中的信息来实际执行公式的唯一方法是动态sql。或者也许是病例陈述?真正涉及到多少种方式和专栏?你可以有一个可用的计算方法表,并让用户选择他们想要的吗?然后你可以编写一个基于他们的选择计算的案例陈述。或根据他们的选择将所有和多个选择陈述联合起来,无论哪一个将帮助您组织您的想法。

如果你真的想留在你正在的路线上,安全不是问题。只需继续使用更多动态SQL并使用临时表来存储结果即可。所以有一个游标可以指出所有不同的公式(或状态)。然后逐步通过该游标,在您的select语句上创建附加条件(例如where state ='CA'或FormulaStatment ='ProductWeight * ShippingCost'),然后将结果插入临时表。在光标后选择你的临时表。

+0

是的,安全风险绝对值得注意。我设置了表单,以便用户只能使用预定义的字段名称和数学运算符来构建公式。这也是一组能够改变计算的用户。 我们目前正在进行8次计算,但数量会增加,可能会增加一倍。 我很欣赏并会考虑这两个想法。我不会使用动态SQL,无论哪种方式最有效地完成工作。 –

+0

没有安全问题,随着公式的增长,动态SQL将成为您未来最小的整体维护,而且实际上代码非常快。在问题的另一方面,8或16条件语句并不难编码。祝你好运! – Matt