[C#] Обработка ExecuteScalar (), когда результаты не возвращаются


Answers

Сначала вы должны убедиться, что ваш объект команды не равен null. Затем вы должны установить свойство CommandText команды в свой SQL-запрос. Наконец, вы должны сохранить возвращаемое значение в переменной объекта и проверить, не является ли оно null до его использования:

command = new OracleCommand(connection)
command.CommandText = sql
object userNameObj = command.ExecuteScalar()
if userNameObj != null then
  string getUserName = userNameObj.ToString()
 ...

Я не уверен в синтаксисе VB, но вы поняли эту идею.

Question

Я использую следующий SQL-запрос и метод ExecuteScalar () для извлечения данных из базы данных Oracle:

sql = "select username from usermst where userid=2"
string getusername = command.ExecuteScalar();

Он показывает мне это сообщение об ошибке:

System.NullReferenceException: ссылка на объект не установлена ​​в экземпляр объекта

Эта ошибка возникает, когда в таблице базы данных нет строки для userid=2

Как я должен справиться с этой ситуацией?




Это самый простой способ сделать это ...

sql = "select username from usermst where userid=2"
object getusername = command.ExecuteScalar();
if (getusername!=null)
{
    //do whatever with the value here
    //use getusername.toString() to get the value from the query
}



Значение SQL NULL

  • эквивалентно в C # - DBNull.Value
  • он ссылается на некоторое значение в столбце NULLABLE
  • сравнение в SQL: IF ( value IS NULL )
  • сравнение в C #: if(obj == DBNull.Value)
  • визуально представленный в C # Quick-Watch как {}

Лучшая практика при чтении с устройства чтения данных:

var reader = cmd.ExecuteReader();
...
var result = (reader[i] == DBNull.Value ? "" : reader[i].ToString());

По моему опыту, есть некоторые случаи, когда возвращаемое значение может отсутствовать, и, таким образом, выполнение не выполняется, возвращая значение null. Примером может служить

select MAX(ID) from <table name> where <impossible condition>

Вышеприведенный скрипт не может найти что-либо, чтобы найти MAX. Таким образом, он терпит неудачу. В этих случаях мы должны сравнить старый способ (сравните с C # null )

var obj = cmd.ExecuteScalar();
var result = (obj == null ? -1 : Convert.ToInt32(obj));



Я использую Oracle . Если ваш sql возвращает числовое значение, которое является int, вам нужно использовать Convert.ToInt32 (объект). Ниже приведен пример:

public int GetUsersCount(int userId)
{
    using (var conn = new OracleConnection(...)){
        conn.Open();
        using(var command = conn.CreateCommand()){
            command.CommandText = "select count(*) from users where userid = :userId";
            command.AddParameter(":userId", userId);            
            var rowCount = command.ExecuteScalar();
            return rowCount == null ? 0 : Convert.ToInt32(rowCount);
        }
    }
}



private static string GetUserNameById(string sId, string connStr)
    {
        System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr);
        System.Data.SqlClient.SqlCommand command;

        try
        {
            // To be Assigned with Return value from DB
            object getusername;

            command = new System.Data.SqlClient.SqlCommand();

            command.CommandText = "Select userName from [User] where userid = @userid";

            command.Parameters.AddWithValue("@userid", sId);

            command.CommandType = CommandType.Text;

            conn.Open();

            command.Connection = conn;

            //Execute
            getusername = command.ExecuteScalar();

            //check for null due to non existent value in db and return default empty string
            string UserName = getusername == null ? string.Empty : getusername.ToString();

            return UserName;


        }
        catch (Exception ex)
        {

            throw new Exception("Could not get username", ex);
        }
        finally
        {
            conn.Close();
        }

    }



Следующая строка:

string getusername = command.ExecuteScalar();

... попытается неявно преобразовать результат в строку, как показано ниже:

string getusername = (string)command.ExecuteScalar();

Регулярный оператор кастинга будет терпеть неудачу, если объект имеет значение null. Попробуйте использовать as-operator, например:

string getusername = command.ExecuteScalar() as string;



Небольшая гипотеза: если вы проверяете стек для исключения, он бросается, тогда поставщик ADO.NET для Oracle читает базовый набор строк, чтобы получить первое значение.

Если нет строки, то нет никакой ценности для поиска.

Для обработки этого случая выполните для чтения и обработайте Next() возвращающее false для случая без соответствия.




Я использовал это в своем VB-коде для возвращаемого значения функции:

Если obj <> Nothing Then Return obj.ToString () Else Return "" End If




Я видел в VS2010 string getusername = command.ExecuteScalar(); дает ошибку компиляции, Невозможно неявно преобразовать объект типа в строку . Поэтому вам нужно написать string getusername = command.ExecuteScalar().ToString(); когда в базе данных нет записи, она дает ошибку Ссылка на объект не установлена ​​в экземпляр объекта, и когда я комментирую '.ToString ()', это не дает никакой ошибки. Поэтому я могу сказать, что ExecuteScalar не выбрасывает исключение. Я думаю, что вопрос, заданный @ Руне Гримстад, прав.




это может помочь .. пример ::

using System;
using System.Data;
using System.Data.SqlClient;

class ExecuteScalar
{
  public static void Main()
  {
    SqlConnection mySqlConnection =new SqlConnection("server=(local)\\SQLEXPRESS;database=MyDatabase;Integrated Security=SSPI;");
    SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
    mySqlCommand.CommandText ="SELECT COUNT(*) FROM Employee";
    mySqlConnection.Open();

    int returnValue = (int) mySqlCommand.ExecuteScalar();
    Console.WriteLine("mySqlCommand.ExecuteScalar() = " + returnValue);

    mySqlConnection.Close();
  }
}

here




Links