Я пытаюсь запустить простой оператор select, а затем вывести результаты в GridView в ASP.NET/C# WebForms. База данных, из которой я извлекаю данные, — это база данных Microsoft SQL Server.
Я пытаюсь передать переменные, полученные от пользовательского ввода, со страницы поиска на страницу результатов через переменные URL. Затем я получу их на странице результатов и применю к запросу. Если страница результатов загружается без предварительного просмотра страницы поиска, строка запроса From
будет неопределенной, и на странице результатов будет отображаться все в наборе данных.
Проблема, с которой я сталкиваюсь, связана с LastName
. Допустим, LastName
является необязательным в поиске и может быть добавлен или не добавлен. FirstName
обязателен и без него страница не может быть отправлена на страницу результатов (для простоты). Однако к странице результатов можно получить доступ без отправки со страницы поиска. В этом случае мы просто делаем select *
из таблицы и заполняем представление сетки всем набором результатов.
Код для страницы результатов:
string fromval = Request.QueryString["from"];
//checking to see if from is next, otherwise just run the regular select * query. If from = next, URL Variables exist. If URL Variables exist, we need to add them to the query.
if (fromval == "next")
{
//set variables from URL, sent from text boxes found on the search page
string sfName = Request.QueryString["pfName"];
string slName = Request.QueryString["plname"];
}
dsResults.SelectParameters.Add("FirstName", sfName.ToString());
//we will never hit this code without providing first name, so we know it will always be there
if (slName != "") //if last name was provided in the search box
{
dsResults.SelectParameters.Add("LastName", slName.ToString());
//if I provide a value for last name, this works fine
}
else
{
//simply set the value of @LastName to "" so like will ignore it. 'WHERE LASTNAME Like ""' should allow every row. Runs fine with LastName LIKE "" in SqlServer Mgt. Studio.
dsResults.SelectParameters.Add("LastName", "");
}
dsResults.SelectCommand = "SELECT * FROM [exampleTable] WHERE FirstName LIKE '%' + @FirstName + '%' AND LastName LIKE '%' + @LastName + '%';"
//check for a postback
if (!Page.IsPostBack)
{
//bind the gridview data
gvResults.DataSource = dsResults;
gvResults.DataBind();
}
Если я укажу значение для Last Name в URL-адресе, он работает без проблем и дает ожидаемые результаты. Если я этого не сделаю, запрос ничего не извлекает, как будто он полностью игнорируется.
Код страницы результатов максимально упрощен:
<asp:GridView ID = "gvResults" runat = "server" AutoGenerateColumns = "False" OnRowDataBound = "gvResults_RowDataBound" CssClass = "table table-bordered">
<Columns>
<asp:BoundField DataField = "FirstName" HeaderText = "FirstName" SortExpression = "FirstName" />
<asp:BoundField DataField = "LastName" HeaderText = "LastName" SortExpression = "LastName" />
</Columns>
</asp:GridView>
<!-- If the query is not changed in the code behind (happens when URL Variables Exist) then it simply selects * from the example table. -->
<asp:SqlDataSource ID = "dsResults" runat = "server" ConnectionString = "myConnectionString" SelectCommand = "SELECT * FROM [exampleTable]"></asp:SqlDataSource>
Код страницы поиска максимально упрощен:
<asp:TextBox ID = "txtFirstName" runat = "server"></asp:TextBox>
<asp:RequiredFieldValidator ID = "RequireFN" runat = "server" ErrorMessage = "First Name is required." ControlToValidate = "txtFirstName"></asp:RequiredFieldValidator>
<asp:TextBox ID = "txtLastName" runat = "server"></asp:TextBox>
<asp:Button ID = "btnSearch" runat = "server" OnClick = "btnSearch_Click" text = "Search" /></div>
Код для страницы поиска:
protected void btnSearch_Click(object sender, EventArgs e)
{
Response.Redirect("ResultsPage.aspx?from=next&pfName = " + txtFirstName.Text + "&plName = " + txtLastName.Text);
}
Я понимаю, что это может быть не лучший способ сделать это, и я открыт для других предложений, если они у вас есть.
Спасибо.
Изменять
SELECT *
FROM [exampleTable]
WHERE FirstName LIKE '%' + @FirstName + '%' AND LastName LIKE '%' + @LastName + '%';
К этому, где вы обходите проверку LastName, когда это пустая строка.
SELECT *
FROM [exampleTable]
WHERE FirstName LIKE '%' + @FirstName + '%' AND (coalesce(@LastName,'') = '' OR LastName LIKE '%' + @LastName + '%');
Кстати, рекомендую поменять
dsResults.SelectParameters.Add("LastName", slName.ToString());
К следующему, где вы полностью указываете тип данных и длину, а не позволяете им автоматически определяться. Такой подход позволит избежать трудно находимых ошибок и потенциально улучшит производительность.
dsResults.SelectParameters.Add(new SqlParameter("@LastName", SqlDbType.NVarChar, 128) { Value = slName.ToString() });
Где вы используете правильный SqlDbType
и длину, чтобы соответствовать столбцу в вашей базе данных.
Вы также можете проверить, что предоставленная строка LastName не является просто длинной последовательностью пробелов, потому что это также не вернет пользователю никаких результатов и может ввести его в заблуждение.
Я ценю ваш быстрый ответ! Я изменил код так, как вы указали, но моя таблица все еще не отображается. Есть ли способ увидеть набор результатов запроса вне таблицы? (Хотелось бы убедиться, что проблема не в чем-то другом). Может быть, что-то вроде WriteLine(результаты)? По-прежнему не получаю никаких полезных сообщений об ошибках, но я точно знаю, что попаду в else (LastName пуст), потому что я вставил WriteLine в начало else и вижу его в VS. Я ценю руководство по полному указанию типа данных! Как только я получу это, я обязательно применю это!
Вы тестируете запрос в SSMS. Пример dbfiddle.
Примечание @brandoonjen Я только что добавил coalesce
к пустому тесту на случай, если автоматический параметр преобразует его в нуль.
Спасибо Дейл! Я собираюсь прервать это на сегодня. У меня есть другие обязательства, о которых я должен позаботиться сегодня вечером, от которых я, к сожалению, не могу отказаться. На данный момент я собираюсь оставить вопрос как есть, потому что я все еще не вижу таблицу, даже после добавления раздела объединения, и надеюсь, что кто-то еще может указать на что-то, что я упустил, но если я не не получите это завтра, я отмечу ваш ответ как принятый. Я ценю вашу помощь!
Возможно, вы пропустили значения NULL и DBNULL.Value. Это немного усиливает предыдущий ответ...
Пожалуйста измените:
if (fromval == "next")
{
//set variables from URL, sent from text boxes found on the search page
string sfName = Request.QueryString["pfName"];
string slName = Request.QueryString["plname"];
}
читать:
if (fromval == "next")
{
//set variables from URL, sent from text boxes found on the search page
string sfName = Request.QueryString["pfName"];
string slName = Request.QueryString["plname"];
}
if (!(sfName is string)) { sfName = ""; }
if (!(slName is string)) { slName = ""; }
И если у вас есть пробелы как вся строка (маловероятно из Request.QueryString), измените на:
dsResults.SelectParameters.Add("LastName", SqlDbType.NVarChar, 128). value = slName.ToString().Trim();
-- условие не требуется, поэтому исключите тест на slName.
Наконец, измените SQL так, чтобы он читался так...
dsResults.SelectCommand = "SELECT * FROM [exampleTable] WHERE FirstName LIKE '%' + @FirstName + '%' AND (@LastName = '' OR LastName LIKE '%' + @LastName + '%');"
Я ценю, что вы, ребята, пытаетесь помочь! Я никогда не мог понять это, и я чувствую, что захожу в тупик, поэтому я думаю, что собираюсь отказаться от этой идеи и попробовать другие способы сделать это. Я где-то читал, что операторы AND могут быть добавлены в конец запроса, если переменная URL существует, и я думаю, что это, вероятно, будет лучшим способом продолжить. Похоже, что SQL ведет себя в Visual Studio иначе, чем в SSMS. Я думаю, что добавление пустых строк в LIKE всегда ничего не вернет. В любом случае, я ценю ваши попытки, ребята!