#asp.net #sql-server #ado.net #sqlcommand
#asp.net #sql-сервер #ado.net #sqlcommand
Вопрос:
Внимание новичку!
Ошибка:
Must declare the scalar variable "@param2".
Must declare the scalar variable "@param2"
(дважды для двух параметров 2)
protected void Button1_Click(object sender, EventArgs e)
{
SqlDataSource ds1 = new SqlDataSource(GetConnectionString(), GetSelectionString());
GridView1.DataSource = ds1;
GridView1.DataBind();
}
и
protected string GetSelectionString() { string SearchString = TextBox1.Text.ToString(); if (RadioButtonList1.SelectedValue == "ALL") { SqlParameter @param2 = new SqlParameter(); SqlCommand SearchAll = new SqlCommand("SELECT Document_Name, Document_Summary FROM Document_Details WHERE (Document_Id IN (SELECT Document_Id FROM Search_Index WHERE (Tag_Id IN (SELECT DISTINCT Tag_Id FROM Tags WHERE (Tag_Name LIKE '%' @param2 '%'))))) UNION SELECT Document_Name, Document_Summary FROM Document_Details AS Document_Details_1 WHERE (Document_Name LIKE '%' @param2 '%')"); SearchAll.Parameters.AddWithValue("@param2", SearchString.ToString()); return (string)SearchAll.CommandText.ToString(); }
Значение TextBox1 будет передано пользователем. Я искал решения около 6 часов... и все еще застрял с этой проблемой. Пожалуйста, какие-либо решения?
Использование VS2008 с подключением MS SQL server 2008 R2.
ПРАВКА 1: ПРЕДОСТАВЛЕНИЕ ПОЛНОГО кода.::
protected string GetSelectionString()
{
string SearchString = "%";
SearchString = SearchString TextBox1.Text.Trim().ToString();
SearchString =SearchString "%";
if (RadioButtonList1.SelectedValue == "ALL")
{
SqlParameter @param2 = new SqlParameter();
SqlCommand SearchAll = new SqlCommand("SELECT Document_Name, Document_Summary FROM Document_Details WHERE (Document_Id IN (SELECT Document_Id FROM Search_Index WHERE (Tag_Id IN (SELECT DISTINCT Tag_Id FROM Tags WHERE (Tag_Name LIKE @param2))))) UNION SELECT Document_Name, Document_Summary FROM Document_Details AS Document_Details_1 WHERE (Document_Name LIKE @param2)");
SearchAll.Parameters.AddWithValue("@param2", SearchString.ToString());
return (string)SearchAll.CommandText.ToString();
}
if (RadioButtonList1.SelectedValue == "FILENAMES")
{
SqlParameter param2 = new SqlParameter();
SqlCommand SearchFileName = new SqlCommand("SELECT Document_Name, Document_Summary FROM Document_Details WHERE (Document_Name LIKE @param2)");
SearchFileName.Parameters.AddWithValue("@param2", SearchString.ToString());
return (string)SearchFileName.CommandText.ToString();
}
protected void Button1_Click(object sender, EventArgs e)
{
SqlDataSource ds1 = new SqlDataSource(GetConnectionString(), GetSelectionString());
GridView1.DataSource = ds1;
GridView1.DataBind();
}
пожалуйста, обратите внимание: я привязываю ее к элементу управления GridView. Это РАБОТАЕТ, если я жестко закодирую значение @param2 в запросе.
ПРАВКА2: ДРУГОЙ ПОДХОД С ДРУГОЙ ОШИБКОЙ:
tried it this way,
SqlCommand temp1 = GetSelectionString();
string temp2 = temp1.CommandText.ToString();
SqlDataSource ds1 = new SqlDataSource(GetConnectionString(), temp1.ToString());
GridView1.DataSource = ds1;
GridView1.DataBind();
....получение новой ошибки
Не удалось найти сервер 'System' в sys.servers. Убедитесь, что было указано правильное имя сервера. При необходимости выполните хранимую процедуру sp_addlinkedserver, чтобы добавить сервер в sys.servers
System.Data.SqlClient.SQLException: не удалось найти сервер 'System' в sys.servers. Убедитесь, что было указано правильное имя сервера. При необходимости выполните хранимую процедуру sp_addlinkedserver, чтобы добавить сервер в sys.servers.
Комментарии:
1. Да, это работает, если вы жестко запрограммируете свое значение, но это НИКОГДА не сработает, если вы хотите настроить параметр.
2. Еще раз обновил мой ответ - попытался предоставить полное решение. Адаптируйте по мере необходимости.
3. Спасибо, Марк. Я попытался адаптировать ваше решение. Но та же ошибка ... параметр не объявлен. Я отказываюсь от внедрения. Я выполню ручную проверку терминов и удалю все не буквенно-цифровые. В любом случае спасибо всем, кто помог мне учиться 🙂
Ответ №1:
Вам нужно использовать @param2
как "автономный" параметр - не упаковывайте его в строку!
SqlCommand SearchAll = new SqlCommand(
"SELECT Document_Name, Document_Summary FROM Document_Details
WHERE (Document_Id IN
(SELECT Document_Id FROM Search_Index
WHERE (Tag_Id IN (SELECT DISTINCT Tag_Id
FROM Tags
WHERE Tag_Name LIKE @param2))))
UNION
SELECT Document_Name, Document_Summary FROM Document_Details AS Document_Details_1
WHERE Document_Name LIKE @param2");
Если вы хотите выполнить поиск строки с %
в начале и конце, вам необходимо ввести это в значение @param2
Также: ваш запрос мог бы работать намного лучше, если бы вы разделили эти подвыборки и использовали одну инструкцию SQL с помощью JOIN для объединения таблиц...
Обновление: ваш подход очень простой недостаток: вы, кажется, ожидаете, что при использовании параметризованных запросов SqlCommand
вы получите полную инструкцию SQL с параметром заполняется при доступе SearchAll.CommandText
- это просто не тот случай - этот параметр @param2
будет не заменить его стоимость!
Итак, в принципе, вы не можете сделать это так, как вы делаете это прямо сейчас - что вам нужно сделать, так это передать обратно SqlCommand
экземпляр - не просто строку! Это никогда не сработает
Обновление # 2: вам нужно сделать что-то вроде этого:
protected void Button1_Click(object sender, EventArgs e)
{
// grab search string from web UI
string searchString = "%" TextBox1.Text.Trim() "%";
// get connection string
string connectionString = GetConnectionString();
SqlDataSource ds1 = new SqlDataSource(connectionString);
// get the SqlCommand to do your SELECT
ds1.SelectCommand = GetSelectCommand(connectionString, searchString);
GridView1.DataSource = ds1;
GridView1.DataBind();
}
и
protected SqlCommand GetSelectCommand(string connectionString, string searchValue)
{
// define query string - could be simplified!
string queryStmt = "SELECT Document_Name, Document_Summary FROM Document_Details WHERE (Document_Id IN (SELECT Document_Id FROM Search_Index WHERE (Tag_Id IN (SELECT DISTINCT Tag_Id FROM Tags WHERE Tag_Name LIKE @param2)))) UNION SELECT Document_Name, Document_Summary FROM Document_Details AS Document_Details_1 WHERE Document_Name LIKE @param2";
// set up a SqlCommand based on the query string and the connection string passed in
SqlCommand cmd = new SqlCommand(queryStmt, connectionString);
// define parameter
cmd.Parameters.Add("@param2", SqlDbType.VarChar, 100);
// set value for parameter
cmd.Parameters["@param2"].Value = searchValue;
// pass back SqlCommand to fill the data source
return cmd;
}
Комментарии:
1. Пробовал. Также не работает : ( Отправил входные данные типа "%hello%" в @param2. Даже тогда та же ошибка.
2. @Ranjanmano: ваш подход в корне ошибочен - вы не можете ожидать, что SqlCommand
.CommandText
будет содержать фактическую инструкцию SQL с заполненным значением параметра - это не работает таким образом в ADO.NET ! Вам нужно передать обратноSqlCommand
объект и использовать его - не полагайтесь на строку!3. попробовал это таким образом, SqlCommand temp1 = GetSelectionString(); строка temp2 = temp1.CommandText. toString(); SqlDataSource ds1 = новый SqlDataSource(GetConnectionString(), temp1. toString()); GridView1.DataSource = ds1; GridView1.DataBind(); .... при получении новой ошибки не удалось найти сервер 'System' в sys.servers. Убедитесь, что было указано правильное имя сервера. При необходимости выполните хранимую процедуру sp_addlinkedserver, чтобы добавить сервер в sys.servers Убедитесь, что было указано правильное имя сервера. При необходимости выполните хранимую процедуру sp_addlinkedserver, чтобы добавить сервер в sys.servers
4. в соответствии с документами / примерами, доступными с использованием % @param, должно быть идеально доступно SELECT * ИЗ каталога, ГДЕ описание ТИПА '%' @searchTerm '%' Другой альтернативой является добавление %XX% перед отправкой параметра по такому
5. Решаемая с использованием имени строки подключения в качестве строки подключения, а затем присвоить его объявленному SqlConnection
Ответ №2:
Я знаю, что это старый вопрос, но я столкнулся с ним, пытаясь вспомнить, как выполнить то же самое, и у меня есть решение. Теперь, когда я прочитал самый последний ответ Саи Каляна Акшинталы, я думаю, что он, возможно, намекал на то же самое.
Ключ в том, что когда вы добавляете параметр в коллекцию параметров SqlDataSource, вам нужно убрать "@" из имени. Ошибка заключается в том, что не отображается параметр с правильным именем, соответствующим имени, переданному в параметризованной строке SQL. В то время как параметр SQL в строке должен быть назван с помощью "@", соответствующие параметры SqlDataSource не должны его использовать.
Вот мой код на C #. Это метод, используемый за веб-формой, которая обеспечивает гибкий поиск в базе данных статей.
protected void CreateArticleSearch()
{
// Declare the base query and start the WHERE clause.
string articleQuery = "SELECT DisplayTitle, Summary, CreateDate, ArticleID FROM Articles ";
string whereClause = "WHERE ";
try
{
// Important, clear the parameters first.
Articles.SelectParameters.Clear();
// Test the field to see if there's anything there.
if (textTitle.Text.Length > 0)
{
// If there is a value, add to the WHERE clause and add a parameter.
whereClause = "DisplayTitle LIKE @ArticleTitle ";
Articles.SelectParameters.Add("ArticleTitle", "%" textTitle.Text "%");
}
// Do the same for each subsequent field except test to see if the
// WHERE clause already holds something and add AND as necessary.
if (textSummary.Text.Length > 0)
{
if (whereClause == "WHERE ")
whereClause = "Summary LIKE @ArticleSummary ";
else
whereClause = "AND Summary LIKE @ArticleSummary ";
Articles.SelectParameters.Add("ArticleSummary", "%" textSummary.Text "%");
}
// Test WHERE clause to see if it contains anything.
// Add it to the base query if it does.
if (whereClause.Length > 6)
articleQuery = whereClause;
// Specify the command type for the SQLDataSource and attach the query.
Articles.SelectCommandType = SqlDataSourceCommandType.Text;
Articles.SelectCommand = articleQuery;
}
catch
{
throw;
}
}
Затем все, что остается, это привязка к данным в GridView, которая предоставляется SqlDataSource. Я использовал это в нескольких приложениях, и это отлично работает.
Эндрю Комо
Комментарии:
1. Я думаю, что
@
префикс IIRC необязателен. Вы пробовали свой код и с ней?2. ДА. Это было последнее, что я исправил, чтобы заставить ее работать. Если вы добавляете параметр к объекту SqlDataSource на странице и проверяете разметку объекта, параметр называется без @ .
Ответ №3:
you concatenating parameter to your query
это неверно в вашем запросе
SqlCommand("SELECT Document_Name, Document_Summary FROM Document_Details WHERE (Document_Id IN (SELECT Document_Id FROM Search_Index WHERE (Tag_Id IN (SELECT DISTINCT Tag_Id FROM Tags WHERE (Tag_Name LIKE %@param2%))))) UNION SELECT Document_Name, Document_Summary FROM Document_Details AS Document_Details_1 WHERE (Document_Name LIKE %@param2%)");
Комментарии:
1. пробовал это. Это отправляет значение '%@param2%' в базу данных. Он не рассматривает param как параметр.
Ответ №4:
Сначала ваше объявление param2 бесполезно: SqlParameter @param2 = новый SqlParameter() Если вы собираетесь ее использовать - попробуйте сделать ее чем-то более значимым, например, DocumentName Second - попробуйте удалить один из параметров? работает ли это? если вы добавите ее во второй раз, произойдет ли сбой? если это так, то измените имя для второго параметра и добавьте его как отдельный параметр.
Комментарии:
1. также удалено объявление. Попробовал это только с одним параметром. Даже тогда это не работает. Та же ошибка.
Ответ №5:
Вы объявляете параметр с именем param2
и используете @param2
, поэтому он застревает. Исправьте это и попробуйте.