#c# #sql-server #asp.net-mvc
#c# #sql-сервер #asp.net-mvc
Вопрос:
var publicFunctions = new PublicFunctionsController();
if (!publicFunctions.CheckSession(Session["id"])) { RedirectToAction("Index", "Home"); };
var src = DateTime.Now;
var date = new DateTime(src.Year, src.Month, src.Day, src.Hour, src.Minute, 00);
var arrow = OverUnder == "Over" ? $"EndTime >= {date}" : OverUnder == "Under" ? $"EndTime <= {date}" : "";
var userCategories = Categoriesb == "" ? "" : $"Categories IN ({Categoriesb})";
var lastId = $"Id > {Id}";
var firstAnd = arrow == "" ? "" : "AND";
var secondAnd = userCategories == "" ? "" : "AND";
var sortByViews = ifViews == 1 ? "ORDER BY Views DESC" : "";
//var strin = $"SELECT TOP 5 StatementTitle, Statement, ArgumentTitle, Argument, Explanation, Categories, EndTime, SessionId, Id FROM Statements WHERE {arrow} {firstAnd} {userCategories} {secondAnd} {lastId} ORDER BY Id DESC {sortByViews}";
//the above works when used as query but below does not
var queryString = "SELECT TOP 5 StatementTitle, Statement, ArgumentTitle, Argument, Explanation, Categories, EndTime, SessionId, Id FROM Statements WHERE @arrow @firstAnd @userCategories @secondAnd @lastId ORDER BY Id DESC @sortByViews";
List<SingleStatementBlog> data = new List<SingleStatementBlog>();
var con = publicFunctions.Connection();
con.Open();
SqlCommand command = new SqlCommand(queryString, con); //figure out or for like clause
command.Parameters.AddWithValue("@arrow", arrow);
command.Parameters.AddWithValue("@firstAnd", firstAnd);
command.Parameters.AddWithValue("@userCategories", userCategories);
command.Parameters.AddWithValue("@secondAnd", secondAnd);
command.Parameters.AddWithValue("@lastId", lastId);
command.Parameters.AddWithValue("@sortByViews", sortByViews);
SqlDataReader reader = command.ExecuteReader();
//error at first and
Когда я запускаю запрос с параметрами, я получаю сообщение об ошибке «ошибка при первом запуске», но когда я запускаю запрос без параметров, он работает (как видно из комментариев). Мне интересно, является ли пустая строка «» причиной сбоя…
Комментарии:
1. Вы не можете передавать операторы в качестве параметров, в качестве параметра Sql могут передаваться только фактические значения
2. Мне не понадобится подготовленный оператор, если я проверяю значения перед раздачей, верно?
3. да, мне это не нужно, я не думаю, что это все новые значения, которые я создал.
4. Обратите внимание на правильный ответ dispose SqlConnection и Command с
using
блоками. Обратите внимание, что AddWithValue — это зло .
Ответ №1:
Вы не можете передавать операторы в качестве параметров в запрос, вместо этого передавая фактические значения.
Вы можете использовать StringBuilder
для построения sql-запроса с параметрами на основе условий.
var src = DateTime.Now;
var date = new DateTime(src.Year, src.Month, src.Day, src.Hour, src.Minute, 00);
var query = new StringBuilder();
query.AppendLine(@"
SELECT TOP 5 StatementTitle, Statement, ArgumentTitle, Argument
, Explanation, Categories, EndTime, SessionId, Id
FROM Statements
WHERE 1 = 1");
if (OverUnder == "Over")
{
query.AppendLine("AND EndTime >= @date");
}
if (OverUnder == "Under")
{
query.AppendLine("AND EndTime <= @date");
}
if (string.IsNullOrEmpty(Categoriesdb) == false)
{
query.AppendLine($"AND Categories IN ({Categoriesb})");
}
if (ifViews == 1)
{
query.AppendLine("ORDER BY Views DESC")
}
else
{
query.AppendLine("ORDER BY Id DESC")
}
using (var connection = createMyConnection())
using (var command = new SqlCommand(query.ToString(), connection))
{
var param = new SqlParameter("@date", SqlDbType.DateTime) {Value = date};
command.Parameters.Add(parameters);
connection.Open();
using (var reader = command.ExecuteReader())
{
// Read the data
}
}
Важно создать SqlParameter с правильными типами базы данных, это повысит производительность запроса и уменьшит возможные ошибки типа.
Обратите внимание, что при передаче Categoriesb вы все еще передаете «необработанные» данные в запрос.
Рассмотрите возможность использования табличных параметров
Комментарии:
1. Спасибо за один = один трюк … не могу поверить, что я не подумал об этом сначала!