如何从其他代码中读取长SQL?

时间:2010-05-05 16:38:56

标签: java sql readability

这是一个非常开放的问题,但我认为它对SQL可读性非常有益。

所以你有一个Java程序,并且你试图从它调用一个怪物SQL语句,有许多子查询和连接。我的问题的起点是这样的字符串常量:

static string MONSTER_STATEMENT = 
  "SELECT  " +
  "   fields" +
  "WHERE "+
  "   fieldA = (SELECT a FROM TableC) " +
  "AND fieldB IN (%s)" +
  "AND fieldC = %d " +
  "FROM "
  "   tableA INNER JOIN tableB ON ...";

稍后使用String.format填充并执行。

你有什么技巧让这种东西可读?你分开你的内部联接吗?你在字符串中缩进SQL本身吗?你把评论放在哪里?请分享你的武器库中的所有技巧。

3 个答案:

答案 0 :(得分:1)

如果我使用像Management Studio这样的管理控制台直接查询数据库,我倾向于按照我的意愿格式化我的SQL语句。因此,当我构建一个SQL语句时,我会把时间放在空格和换行符中。消耗的额外空间与能够读取SQL的时间节省相比是无关紧要的,我应该将其打印出来或使用SQL Profiler捕获它。所以,我倾向于使用StringBuilder来组合我的SQL:

StringBuilder sql = new StringBuilder();
sql.append("Select ....");
sql.append("\t\n, AdditionalCol, ...");
sql.append("\nFrom ...");
sql.append("\n  Inner Join ...");
sql.append("\n      On ColA =  ...");
sql.append("\nWhere Col1 = (");
sql.append("\n          Select a");
sql.append("\n          From TableC");
sql.append("\n          ");
sql.append("\n  And ColB In(%s)");
sql.append("\n  And ColC = %d");

答案 1 :(得分:1)

围绕构建过程的帮助程序类可能对您有所帮助。那可能是一个:http://openhms.sourceforge.net/sqlbuilder/

无论如何,总是要准备好陈述。

答案 2 :(得分:0)

这样复杂的SQL应该在一个准备好的语句中,而不是由String.format组合在一起以避免SQL注入问题。

我执行以下两项操作之一:将其包装在可调用语句中或将其放在配置/ xml文件中。 Java源文件是复杂SQL的坏地方。

话虽如此,IDEA还有一种语言格式化功能,可以将Java中的字符串格式化为不同的语言(基于传递给它们的方法或基于注释),这样可以提供帮助。

编辑:鉴于您的情况,我同意可调用的语句可能不可行。准备好的语句仍然值得,即使对于内部开发,只是因为带有撇号的参数可以将所有内容都搞砸(即使没有攻击者),所以IMO还是值得做额外的工作来创建字符串代码中的动态(String.format或其他任何东西)仅用于不能作为参数传递的部分(如示例中的临时表名),然后将其用作准备语句,为其余部分传递适当的参数。

至于保持它不那么难看,它看起来像配置/ xml类型文件是我想要的。