C # подключен к SQL, не возвращая значение - PullRequest
0 голосов
/ 20 мая 2019

Я подключился к SQL Server с помощью C #. Теперь я должен сделать 3 варианта. Один - выполнить процедуру, которая работает отлично, второй - извлечь некоторые данные, что тоже сделано, и последний вариант - выбрать конкретную страну, которую выбрал пользователь, и показать среднее значение для рестораны, расположенные в этой стране.

Теперь запрос работает в SSMS, как я его тестировал. Однако, когда я попытался запустить его, как и другие 2 варианта, он дал мне ошибку соединения.

Код ниже - это код C # второго варианта, который работает:

public static void showStatistics()
{
    string connetionString = "Data Source=DESKTOP-RV4VR9I;Initial 
Catalog=Assignment;User ID=Jake;Password=1234;Integrated Security=True";

    SqlConnection conn = new SqlConnection(connetionString);
    SqlCommand mySQL = new SqlCommand("BEGIN TRANSACTION SET     
TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT TOP 1 country, score, 
year FROM main.[stats] ORDER BY [Statistics Generated] DESC COMMIT         
TRANSACTION", conn);

    try
    {
        conn.Open();

        SqlDataReader dataReader = mySQL.ExecuteReader();

        string holderCountry = "";
        string holderScore = "";
        string holderYear = "";

        while (dataReader.Read())
        {
             holderCountry += dataReader["country"];
             holderScore += dataReader["score"];
             holderYear += dataReader["year"];
        }

        Console.WriteLine("\nCountry: "+holderCountry);
        Console.WriteLine("Score: " + holderScore);
        Console.WriteLine("Year: " + holderYear+"\n");

        conn.Close();
    }    
    catch (Exception e)
    {
        Console.WriteLine("Can not open connection ! ");
    }
}

Следующий фрагмент кода - это код, выдающий мне ошибку:

public static void showCountryAverage(string countryChoice)
        {
            string connetionString = "Data Source=DESKTOP-RV4VR9I;Initial 
Catalog=Assignment;User ID=Jake;Password=1234;Integrated Security=True";
            SqlConnection conn = new SqlConnection(connetionString);
            SqlCommand mySQL = new SqlCommand("BEGIN TRANSACTION SET 
TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT c.country, 
AVG(CAST(re.score AS DECIMAL(8, 6))) FROM main.country c JOIN 
main.restaurant r ON(c.countryId = r.countryId) JOIN main.review re 
ON(r.restaurantId = re.restaurantId) WHERE c.country = "+countryChoice+" 
GROUP BY c.country COMMIT TRANSACTION", conn);
            try
            {
                conn.Open();
                SqlDataReader dataReader = mySQL.ExecuteReader();
                string holderCountry = "";
                while (dataReader.Read())
                {

                    holderCountry += dataReader["country"];
                    holderCountry += dataReader["AVG(CAST(re.score AS     
DECIMAL(8, 6)))"];
                }
                Console.WriteLine("\nCountry: " + holderCountry);
                conn.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Can not open connection ! ");
            }
        }

Спасибо!

Это ошибка

System.Data.SqlClient.SqlException (0x80131904): неверное имя столбца 'Италия'.

в System.Data.SqlClient.SqlConnection.OnError (исключение SqlException, логическое прерывание, действие 1 wrapCloseInAction)<br> at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action 1 wrapCloseInAction)
в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning (TdsParserStateObject stateObj, логический callerHasConnectionLock, логический asyncClose) в System.Data.SqlClient.TdsParser.TryRun (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, данные Boolean) в System.Data.SqlClient.SqlDataReader.TryConsumeMetaData () в System.Data.SqlClient.SqlDataReader.get_MetaData () в System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, логическое значение isInternal, логическое значение дляDescribeParameterEncryption, логическое значение mustCacheForAlwaysEnc) в System.Data.SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, логический returnStream, логический асинхронный, Int32-тайм-аут, задача и задача, логический asyncWrite, Boolean в System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, логический returnStream, метод String, завершение TaskCompletionSource`1, тайм-аут Int32, Task & task, Boolean & usedCache в Boolean, Boolean, Boolean, Boolean, Boolean), Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean: Boolean в System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, логический returnStream, метод String) в System.Data.SqlClient.SqlCommand.ExecuteReader (поведение CommandBehavior, метод String) в System.Data.SqlClient.SqlCommand.ExecuteReader () в Database_Number_6.Program.showCountryAverage (String countryChoice) в C: \ Users \ Пользователь \ Desktop \ 000SWD6.1B \ 2ndSemester \ Database 2 \ Assignment \ Database_Number_6 \ Database_Number_6 \ Program.cs: строка 133 ClientConnectionId: 74fbcdc0-47ec-41cc-839d-0b05b13661df Номер ошибки: 207, состояние: 1, класс: 16

1 Ответ

4 голосов
/ 20 мая 2019

Проблема Неверное имя столбца Италия вызвана тем, что вы объединили строку Италия с вашей командой sql. В SQL, если вы хотите выразить постоянное строковое значение, вы должны поместить его в одинарные кавычки, например 'Italy' . Без кавычек механизм синтаксического анализа sql считает, что вы хотите сравнить значения в столбце country со значениями в столбце Italy . Таким образом, добавление кавычек может решить проблему, но это хорошо известный источник разбора ошибок (что, если значение содержит в себе одиночную кавычку? И я даже не начинаю говорить о датах) Хуже, этот подход позволяет легко взломать базу данных через Sql Injection .

Единственный правильный способ создания запросов, для которых нужны значения кода, - это использование параметров

SqlCommand mySQL = new SqlCommand(@".....
                                   SELECT c.country, 
                                   ....
                                   FROM main.country c 
                                   ....
                                   WHERE c.country = @country
                                   GROUP BY .....", con);
mySql.Parameters.Add("@country", SqlDbType.NVarChar).Value = countryCode;
 ....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...