当前位置: 首页 > 面试题库 >

有标准的方法可以动态生成sql吗?

亢琦
2023-03-14
问题内容

我想问一下其他程序员如何生成动态SQL字符串以作为SQLCommand对象的CommandText执行。

我正在生成包含用户生成的WHERE子句和SELECT字段的参数化查询。有时查询很复杂,我需要对不同部分的构建方式进行大量控制。

当前,我正在使用许多循环和switch语句来生成必要的SQL代码片段并创建所需的SQL参数对象。这种方法很难遵循,并且使维护工作变得很繁琐。

有没有更清洁,更稳定的方法?

有什么建议?

编辑:要添加详细信息到我以前的文章:

  1. 由于要求,我无法真正为查询模板。它只是改变太多了。
  2. 我必须允许聚合函数,例如Count()。这会对“分组依据/具有”子句产生影响。它还会导致嵌套的SELECT语句。反过来,这会影响
  3. 一些联系人数据存储在XML列中。用户可以一起查询AS WELL AS和其他关系列的数据。结果是xmlcolumns不能出现在Group By子句[sql语法]中。
  4. 我正在使用使用Row_Number()SQL函数的高效分页技术。结果是我必须使用一个Temp表,然后在选择我的子集之前获取@@ rowcount,以避免再次查询。

我将展示一些代码(恐怖!),以便你们对我要处理的内容有个了解。

sqlCmd.CommandText = "DECLARE @t Table(ContactId int, ROWRANK int" + declare
      + ")INSERT INTO @t(ContactId, ROWRANK" + insertFields + ")"//Insert as few cols a possible
      + "Select ContactID, ROW_NUMBER() OVER (ORDER BY " + sortExpression + " "
      + sortDirection + ") as ROWRANK" // generates a rowrank for each row
      + outerFields
      + " FROM ( SELECT c.id AS ContactID"
      + coreFields
      + from         // sometimes different tables are required 
      + where + ") T " // user input goes here.
      + groupBy+ " "
      + havingClause //can be empty
      + ";"
      + "select @@rowcount as rCount;" // return 2 recordsets, avoids second query
      + " SELECT " + fields + ",field1,field2" // join onto the other cols n the table
      +" FROM @t t INNER JOIN contacts c on t.ContactID = c.id" 
      +" WHERE ROWRANK BETWEEN " + ((pageIndex * pageSize) + 1) + " AND " 
      + ( (pageIndex + 1) * pageSize); // here I select the pages I want

在此示例中,我正在查询XML数据。对于纯关系数据,查询要简单得多。每个部分变量都是StringBuilders。where子句的构建方式如下:

// Add Parameter to SQL Command
AddParamToSQLCmd(sqlCmd, "@p" + z.ToString(), SqlDbType.VarChar, 50, ParameterDirection.Input, qc.FieldValue);
// Create SQL code Fragment
where.AppendFormat(" {0} {1} {2} @p{3}", qc.BooleanOperator, qc.FieldName, qc.ComparisonOperator, z);

问题答案:

我需要在我最近的一个项目中执行此操作。这是我用于生成SQL的方案:

  • 查询的每个组件都由一个对象表示(在我的情况下,该对象是映射到DB中表的Linq-to-Sql实体)。因此,我有以下类:查询,SelectColumn,联接,WhereCondition,排序,GroupBy。这些类中的每一个都包含与查询的该组件有关的所有详细信息。
  • 最后五个类都与Query对象有关。因此,Query对象本身具有每个类的集合。
  • 每个类都有一个可以为其表示的查询部分生成SQL的方法。因此,创建整体查询最终将调用Query.GenerateQuery(),后者依次枚举所有子集合并调用其各自的GenerateQuery()方法

仍然有些复杂,但是最后您知道查询的每个单独部分的SQL生成起源于何处(而且我认为没有任何大的switch语句)。并且不要忘记使用StringBuilder。



 类似资料:
  • 我想看一下 SQL 标准中的内容 然后我去谷歌搜索了一下 chatGPT 给我的关键字 但是出来的结果,貌似都是和某一款 DB 具体实现相关,而不是一个通用的 sql 标准

  • 我生成SQL语句的代码工作正常-但是我在为$stmt生成字符串时遇到了一个问题-

  • 我想实现一个有五个可选变量的搜索函数,并且在每个组合中,所以一个开关/案例不是一个可能的方法。所以我不能使用构建在Spring启动函数,因为它们不是动态的(如果我错了,请纠正我)。我知道crudrepository中有@查询注释,但是没有办法用可选参数编写查询?我试图用jpa编写我自己的数据库访问,没有Spring启动CrudRepository的帮助。我在手册中读到这应该可以工作: 但问题是,我

  • 我试图组装一个SQL生成器,这样我就可以动态地构建SQL语句,并将它们传递到Spark Job Server上。当预先知道表列时,似乎很容易(使用JOOQ): JOOQ“field”似乎是一个强类型对象。 是否有一种方法可以使用这种动态构造的列列表来构建这样的JOOQ select语句?

  • 本文向大家介绍动态JSP页生成静态HTML的方法,包括了动态JSP页生成静态HTML的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了动态JSP页生成静态HTML的方法。分享给大家供大家参考。具体如下: 具体实现: 利用Filter的过滤功能把*.jsp过滤出来,判断是否存在对应的.html文件,如果不存在对应的.html文件,则将其内容读出写入指定的.html文件,再跳转到对应的.h

  • 本文向大家介绍详解php中生成标准uuid(guid)的方法,包括了详解php中生成标准uuid(guid)的方法的使用技巧和注意事项,需要的朋友参考一下 UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。 通常平台 会提供生成UUID的API。UUID按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。 由以 下几部