Необходимо объявить скалярную переменную @param проблема

#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 , поэтому он застревает. Исправьте это и попробуйте.