결과가 반환되지 않을 때 ExecuteScalar () 처리
다음 SQL 쿼리와 ExecuteScalar()
Oracle 데이터베이스에서 데이터를 가져 오는 방법을 사용하고 있습니다.
sql = "select username from usermst where userid=2"
string getusername = command.ExecuteScalar();
이 오류 메시지가 표시됩니다.
System.NullReferenceException : 개체 참조가 개체의 인스턴스로 설정되지 않았습니다.
이 오류는에 대한 데이터베이스 테이블에 행이 없을 때 발생합니다 userid=2
.
이 상황을 어떻게 처리해야합니까?
DbCommand.ExecuteScalar에 대한 MSDN 설명서에 따르면 :
결과 집합에서 첫 번째 행의 첫 번째 열을 찾을 수없는 경우 Null 참조 (Visual Basic의 경우 Nothing)이 반환됩니다. 데이터베이스의 값이 null이면 쿼리는 DBNull.Value를 반환합니다.
다음 스 니펫을 고려하십시오.
using (var conn = new OracleConnection(...)) {
conn.Open();
var command = conn.CreateCommand();
command.CommandText = "select username from usermst where userid=2";
string getusername = (string)command.ExecuteScalar();
}
런타임시 (ODP.NET에서 테스트되었지만 모든 ADO.NET 공급자에서 동일해야 함) 다음과 같이 작동합니다.
- 행이 존재하지 않는 경우의 결과
command.ExecuteScalar()
는 널 (null)이며, 이는 널 문자열로 캐스트되고에 할당됩니다getusername
. - 행이 존재하지만 사용자 이름에 NULL을 (당신의 DB에서이 가능하다조차?)이있는 경우의 결과
command.ExecuteScalar()
이다DBNull.Value
결과InvalidCastException
.
어쨌든 NullReferenceException
가능하지 않아야하므로 문제가 다른 곳에있을 수 있습니다.
먼저 명령 개체가 null이 아닌지 확인해야합니다. 그런 다음 명령의 CommandText 속성을 SQL 쿼리로 설정해야합니다. 마지막으로 반환 값을 개체 변수에 저장하고 사용하기 전에 null인지 확인해야합니다.
command = new OracleCommand(connection)
command.CommandText = sql
object userNameObj = command.ExecuteScalar()
if (userNameObj != null)
string getUserName = userNameObj.ToString()
...
VB 구문에 대해 잘 모르겠지만 아이디어를 얻었습니다.
방금 사용했습니다.
int? ReadTerminalID()
{
int? terminalID = null;
using (FbConnection conn = connManager.CreateFbConnection())
{
conn.Open();
FbCommand fbCommand = conn.CreateCommand();
fbCommand.CommandText = "SPSYNCGETIDTERMINAL";
fbCommand.CommandType = CommandType.StoredProcedure;
object result = fbCommand.ExecuteScalar(); // ExecuteScalar fails on null
if (result.GetType() != typeof(DBNull))
{
terminalID = (int?)result;
}
}
return terminalID;
}
다음 줄 :
string getusername = command.ExecuteScalar();
... 다음과 같이 결과를 암시 적으로 문자열로 변환하려고합니다.
string getusername = (string)command.ExecuteScalar();
개체가 null이면 일반 캐스팅 연산자가 실패합니다. 다음과 같이 as-operator를 사용해보십시오.
string getusername = command.ExecuteScalar() as string;
sql = "select username from usermst where userid=2"
var _getusername = command.ExecuteScalar();
if(_getusername != DBNull.Value)
{
getusername = _getusername.ToString();
}
이것은 도움이 될 수 있습니다 .. 예 ::
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();
}
}
이에서 여기
행을 읽기 전에 항상 확인하십시오.
if (SqlCommand.ExecuteScalar() == null)
{
}
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));
이것이 가장 쉬운 방법입니다 ...
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
}
귀하의 경우에는 기록이 함께 존재하지 않는 userid=2
또는 값이 SQL 명령에 사용 된 쿼리 결과를 찾을 수없는 경우 있기 때문에, 첫 번째 열에서 NULL 값을 포함 할 수있다 ExecuteScalar()
반환 null
.
또는 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();
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();
}
}
약간의 추측 : 스택에서 예외를 확인하면 예외가 발생하면 Oracle 용 ADO.NET 공급자가 기본 행 집합을 읽고 첫 번째 값을 가져옵니다.
행이 없으면 찾을 값이 없습니다.
이 경우를 처리하려면 판독기에 대해 실행하고 Next()
일치하지 않는 경우 false 반환을 처리 합니다.
Microsoft Application Block DLL과 함께 사용합니다 (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 ;
}
I have seen in VS2010 string getusername = command.ExecuteScalar();
gives compilation error, Cannot implicitly convert type object to string. So you need to write string getusername = command.ExecuteScalar().ToString();
when there is no record found in database it gives error Object reference not set to an instance of an object and when I comment '.ToString()', it is not give any error. So I can say ExecuteScalar
not throw an exception. I think anserwer given by @Rune Grimstad is right.
I had this issue when the user connecting to the database had CONNECT permissions, but no permissions to read from the database. In my case, I could not even do something like this:
object userNameObj = command.ExecuteScalar()
Putting this in a try/catch (which you should probably be doing anyway) was the only way I could see to handle the insufficient permission issue.
If you either want the string
or an empty string
in case something is null, without anything can break:
using (var cmd = new OdbcCommand(cmdText, connection))
{
var result = string.Empty;
var scalar = cmd.ExecuteScalar();
if (scalar != DBNull.Value) // Case where the DB value is null
{
result = Convert.ToString(scalar); // Case where the query doesn't return any rows.
// Note: Convert.ToString() returns an empty string if the object is null.
// It doesn't break, like scalar.ToString() would have.
}
return result;
}
/* Select some int which does not exist */
int x = ((int)(SQL_Cmd.ExecuteScalar() ?? 0));
I used this in my vb code for the return value of a function:
If obj <> Nothing Then Return obj.ToString() Else Return "" End If
Try this code, it appears to solve your problem.
Dim MaxID As Integer = Convert.ToInt32(IIf(IsDBNull(cmd.ExecuteScalar()), 1, cmd.ExecuteScalar())
)
I'm using Oracle. If your sql returns numeric value, which is int, you need to use Convert.ToInt32(object). Here is the example below:
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);
}
}
}
Try this
sql = "select username from usermst where userid=2"
string getusername = Convert.ToString(command.ExecuteScalar());
ReferenceURL : https://stackoverflow.com/questions/1999020/handling-executescalar-when-no-results-are-returned
'Development Tip' 카테고리의 다른 글
Http StaticInjectorError에 대한 공급자가 없습니다. (0) | 2021.01.05 |
---|---|
인스턴스화 된 개체에 메서드 추가 (0) | 2021.01.05 |
헤더에서 작동하지 않는 상수 변수 (0) | 2021.01.05 |
PostgreSQL에서 dblink를 사용 (설치)하는 방법은 무엇입니까? (0) | 2021.01.05 |
PHP는 배열의 마지막 3 개 요소를 가져옵니다. (0) | 2021.01.05 |