[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

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




Кроме того, вы можете использовать DataTable для проверки наличия какой-либо строки:

SqlCommand cmd = new SqlCommand("select username from usermst where userid=2", conn);
SqlDataAdapter adp = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adp.Fill(dt);
string getusername = "";
// assuming userid is unique
if (dt.Rows.Count > 0)
    getusername = dt.Rows[0]["username"].ToString();



Я использую 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);
        }
    }
}



У меня была эта проблема, когда пользователь, подключившийся к базе данных, имел разрешения CONNECT, но никаких прав на чтение из базы данных. В моем случае я даже не мог сделать что-то вроде этого:

object userNameObj = command.ExecuteScalar()

Помещение этого в try / catch (которое вы, вероятно, должны делать в любом случае) было единственным способом, с помощью которого можно было справиться с проблемой недостаточного разрешения.




Значение 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. Таким образом, он терпит неудачу. В этих случаях мы должны сравнить старый способ

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



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

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();
  }
}

отсюда




Я использую его, как это, с DLL приложения Microsoft Application Block (его справочная библиотека для операций DAL)

public string getCopay(string PatientID)
{
       string sqlStr = "select ISNULL(Copay,'') Copay from Test where patient_id=" + PatientID ;
        string strCopay = (string)SqlHelper.ExecuteScalar(CommonCS.ConnectionString, CommandType.Text, sqlStr);
                if (String.IsNullOrEmpty(strCopay))
                    return "";
                else
                    return strCopay ;
}



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

string getusername = command.ExecuteScalar();

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

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

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

string getusername = command.ExecuteScalar() as string;



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

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




В вашем случае либо запись не существует с userid=2 либо может содержать нулевое значение в первом столбце, потому что если для результата запроса, используемого в команде SQL, не ExecuteScalar() , ExecuteScalar() возвращает значение null .