通过Ant脚本消除对动态SQL的依赖

时间:2012-01-13 15:38:57

标签: mysql eclipse ant

我已经承担了许多存储过程的责任,这些过程采用以下形式:

create procedure getFoos()
begin
    set @v_sql :=                '';
    set @v_sql := concat(@v_sql, 'select distinct ', getFooFields('f', 'b'), ' ');
    set @v_sql := concat(@v_sql, 'from Foos f ');
    set @v_sql := concat(@v_sql, '  left join Bars b on f.barID= b.barID');
    set @v_sql := concat(@v_sql, 'where f.someDate is null ');
    set @v_sql := concat(@v_sql, '  and b.someID in (1, 2, 3) ');
    set @v_sql := concat(@v_sql, '  and b.someBool = true ');
    set @v_sql := concat(@v_sql, 'order by f.name ');

    prepare s1 from @v_sql;
    execute s1;
    deallocate prepare s1;  
end;

如您所见,正在使用动态SQL,以便可以内联函数getFooFields。该函数仅用于构建所选字段的字符串:

create function getFooFields(
    i_aliasForFoo varchar(32),
    i_aliasForBar varchar(32)
) returns text
reads sql data
begin
    declare v_fields text default '';

    set v_fields := concat(v_fields, i_aliasForFoo, '.fooID as fooId', ', ');
    set v_fields := concat(v_fields, i_aliasForFoo, '.someDate as someDate ', ', ');
    set v_fields := concat(v_fields, i_aliasForFoo, '.name as name', ', ');
    -- additional Foo fields
    set v_fields := concat(v_fields, i_aliasForBar, '.someID as someID ', ', ');
    set v_fields := concat(v_fields, i_aliasForBar, '.someBool as someBool ', ', ');
    -- additional Bar fields

    return v_fields;
end;

这样做的原因似乎是更好的可维护性 - 当FoosBars表被更改时,只需要在一个函数中进行更改,而不是在许多过程中进行更改。然而,这是以使用动态SQL为代价的,以及每次调用它时构建相同字符串的额外函数。我想知道在运行之前是否有办法保持可维护性。

实际上,我们在Eclipse中管理我们的SQL并使用Ant来按摩这些文件,然后在每次部署之前在数据库上运行它们。有没有办法让Ant编写脚本以完成getFooFields的工作?我想象如下:

select distinct <%foofields%> from Foos
...

Ant将使用与<%foofields%>正在构建的字符串类似的字符串替换getFooFields。但当然,getFooFields采用参数这一事实使得这一点更加复杂,因此我不确定它是如何工作的。

这个想法完全被误导了吗?我几乎没有任何使用Ant的经验,所以我无法分辨。或者,我可以通过其他方式删除这些过程对动态SQL的依赖,同时保持它们的可维护性吗?

1 个答案:

答案 0 :(得分:1)

如果getFooFields最常用于选择表foo中的所有字段,那么最好使用select * from foo而不是动态SQL和函数的组合。

如果它是foo中经常作为一个组出现的字段的子集,那么通过将该子集创建为视图并查询该视图可能会更好。

如果getFooFields从另一个应用程序中选择字段列表以从foo中进行选择,那么您必须检查这是否有意义。 foo中有多少个字段?您多久只需要少数这些领域?你是否为这种“优化”提取了足够多的记录才有意义?最有可能的是,你不是,只是拉动公共领域或所有领域会更好。