Я хочу спросить, как другие программисты производят динамические строки SQL для выполнения в качестве CommandText объекта SQLCommand.
Я создаю параметризованные запросы, содержащие пользовательские предложения WHERE и поля SELECT. Иногда запросы сложны, и мне нужен большой контроль над тем, как создаются разные части.
В настоящее время я использую множество циклов и операторов switch для создания необходимых фрагментов кода SQL и для создания необходимых параметров параметров SQL. Этот метод трудно выполнить, и это делает техническое обслуживание реальной задачей.
Есть ли более чистый, более стабильный способ сделать это?
Любые предложения
EDIT: Чтобы добавить деталь к моему предыдущему сообщению:
1. Я не могу настроить свой запрос из-за требований. Это просто слишком сильно меняется.
- Я должен разрешить агрегатные функции, такие как Count(). Это имеет последствия для предложения Group By/Have. он также вызывает вложенные операторы SELECT. Это, в свою очередь, влияет на имя столбца, используемое
- Некоторые данные контакта хранятся в столбце XML. Пользователи могут запрашивать эти данные AS WELL AS и другие реляционные столбцы вместе. Следствием является то, что xmlcolumns не могут появляться в предложениях Group By [синтаксис sql].
- Я использую эффективную технику подкачки, которая использует функцию 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. Где кладки строятся так:
//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);