回答

收藏

动态生成标准方法sql吗?

技术问答 技术问答 268 人阅读 | 0 人回复 | 2023-09-14

我想问问其他程序员如何生成动态SQL作为字符串SQLCommand对象的CommandText执行。
' R0 V5 j. [  r% z- w3 v我正在生成包含用户生成的产品WHERE子句和SELECT参数字段查询。有时查询非常复杂,我需要控制不同部分的构建方法。( T6 A' }# ~9 ^2 `! S1 w2 k
目前,我正在使用许多循环和switch生成必要的句子SQL创建所需的代码片段并创建所需的代码片段SQL参数对象。这种方法很难遵循,维护工作也很繁琐。! A; y# k& X1 h- {  }; O! D
有没有更清洁、更稳定的方法?) P% \& @- _- C# V7 p
有什么建议?
: }' ?  \6 A, C8 V  {4 f& v) z编辑:要添加详细信息到我以前的文章:
2 A1 V( A* `" o2 U  X[ol]因为要求,我不能真正查询模板。只是变化太大了。9 P* |  R( }! O; `4 ?/ `% D- X! |
我必须允许聚合函数,例如Count()。这将影响分组依据/有子句。它还会导致嵌套SELECT句子。另一方面,它会影响' G. w; u' A3 M/ p( _/ N+ b0 v
存储一些联系人数据XML列中。用户可以一起查询。AS WELL AS与其他关系列的数据。xmlcolumns不能出现在Group By子句[sql语法]中。- |( c4 N$ h: r6 g. Q6 I
我在用Row_Number()SQL函数的高效分页技术。结果是我必须使用一个Temp然后在选择我的子集之前获得表格@@ rowcount,避免再次查询。[/ol]我会显示一些代码(恐怖)!),这样你就可以知道我要处理什么了。' G  F2 N2 ?# i) F8 w6 J& ^
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构建子句的方法如下:( Q; h+ V+ i2 g9 [7 ^" N
// Add Parameter to SQL CommandAddParamToSQLCmd(sqlCmd,"@p"   z.ToString(),SqlDbType.VarChar,50,ParameterDirection.Input,qc.FieldValue);// Create SQL code Fragmentwhere.AppendFormat(" @p{3}",qc.BooleanOperator,qc.FieldName,qc.ComparisonOperator,z);                $ a- O% M# s* {6 Z! |
    解决方案:                                                               
2 z, G# F5 W+ A                                                                我需要在我最近的一个项目中执行这个操作。这是我用来生成的SQL的方案:0 }3 S$ [0 u( R: k9 ^3 g
查询的每个组件都由一个对象表示(在我的情况下,对象是映射的DB中表的Linq-to-Sql因此,我有以下类别:查询,SelectColumn,联接,WhereCondition,排序,GroupBy。这些类别中的每一个都包含与查询组件相关的所有详细信息。
* R% v6 n% `! l3 M5 x* p最后五类都和Query对象有关。Query对象本身有每个类别的集合。
/ g+ z- X' N/ \% R9 u/ H$ n6 @( h$ q- o每个类都有一个可以表示的查询部分SQL方法。因此,创建整体查询最终将被调用Query.GenerateQuery()后者依次枚举所有子并调用其各自GenerateQuery()方法
还是有点复杂,但但最终你知道每个单独部分的查询SQL生成起源于哪里(而且我觉得没有什么大的)switch语句)。别忘了用。StringBuilder。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则