I have created a method to check the database every time data is added to it. The reason for this is to check for duplicate primary keys(manually generated).The problem I'm facing is that the method always returns null value even when the data exists in the database.
Here's my code :
public int checkComRegnumberAvailable(string conRegnumber)
{
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT RegNumber FROM OtherCompanyData";
con.Open();
//string result = ((string)cmd.ExecuteScalar());
string result = (string)cmd.ExecuteScalar();
cmd.ExecuteNonQuery();
if (result == null)
{
return 0;
}
if (result.Equals(conRegnumber))
{
return 1;
}
else
{
return 2;
}
}
}
You can to use a DataReader in order to retrive informatiom from your database. The link below shows a fine example of how to use it in your code.
https://msdn.microsoft.com/en-us/library/haa3afyz%28v=vs.110%29.aspx
Related
Can someone tell my why my expectedNumber reader throws an error
The name reader does not exist in its current context
As far as I can see all this is doing is reading the first row and first column, don't understand why the reader is throwing a tantrum.
It doesn't like the line:
ExpectedNumber = reader.GetInt16(0);
The query is :
SELECT TOP (1) [ExpectedNumber]
FROM [dbo].[MyDatabase]
WHERE id = '{0}'
Code:
try
{
using (SqlCommand cmd = new SqlCommand(string.Format(Query, id), Connection))
{
Connection.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Check is the reader has any rows at all before starting to read.
if (reader.HasRows)
{
int ExpectedNumber = 0;
// Read advances to the next row.
while (reader.Read() == true)
{
// To avoid unexpected bugs access columns by name.
ExpectedNumber = reader.GetInt16(0);
}
Connection.Close();
return ExpectedResult;
}
Assert.Fail("No results returned from expected result query");
return 0;
}
}
}
catch (Exception e)
{
Connection.Close();
throw;
}
You should escape your query parameters, otherwise your code is vulnerable to SQL injection attacks, also, by using command parameters as in the example below you can make sure you are using the right data type (it seems you are trying to pass an int id as a string).
You are just trying to get one value so you don't need to use a reader and can use ExecuteScalar instead.
Finally, you don't need to handle closing the connection if you enclose it in a using block so you can avoid the try catch block as well.
string query = "SELECT TOP (1) [ExpectedNumber] FROM [dbo].[MyDatabase] WHERE id = #id";
using (var connection = new SqlConnection("connStr"))
{
connection.Open();
using (var cmd = new SqlCommand(query, connection))
{
cmd.Parameters.Add("#id", SqlDbType.Int).Value = id;
object result = cmd.ExecuteScalar();
if (result != null && result.GetType() != typeof(DBNull))
{
return (int)result;
}
Assert.Fail("No Results Returned from Expected Result Query");
return 0;
}
}
Note: this code assumes you are using SQL Server, for other systems the format of the parameters in the connection string might change, e.g. for Oracle it should be :id instead of #id.
I have a very silly problem. I am doing a select, and I want that when the value comes null, return an empty string. When there is value in sql query, the query occurs all ok, but if there is nothing in the query, I have to give a sqlCommand.CommandTimeout greater than 300, and yet sometimes gives timeout. Have a solution for this?
public string TesteMetodo(string codPess)
{
var vp = new Classe.validaPessoa();
string _connection = vp.conString();
string query = String.Format("SELECT COUNT(*) FROM teste cliente WHERE cod_pess = {0}", codPess);
try
{
using (var conn = new SqlConnection(_connection))
{
conn.Open();
using (var cmd = new SqlCommand(query, conn))
{
SqlDataReader dr = cmd.ExecuteReader();
if(dr.HasRows)
return "";
return codPess;
}
}
}
You should probably validate in the UI and pass an integer.
You can combine the usings to a single block. A bit easier to read with fewer indents.
Always use parameters to make the query easier to write and avoid Sql Injection. I had to guess at the SqlDbType so, check your database for the actual type.
Don't open the connection until directly before the .Execute. Since you are only retrieving a single value you can use .ExecuteScalar. .ExecuteScalar returns an Object so must be converted to int.
public string TesteMetodo(string codPess)
{
int codPessNum = 0;
if (!Int32.TryParse(codPess, out codPessNum))
return "codPess is not a number";
var vp = new Classe.validaPessoa();
try
{
using (var conn = new SqlConnection(vp.conString))
using (var cmd = new SqlCommand("SELECT COUNT(*) FROM teste cliente WHERE cod_pess = #cod_pess", conn))
{
cmd.Parameters.Add("#cod_pess", SqlDbType.Int).Value = codPessNum;
conn.Open();
int count = (int)cmd.ExecuteScalar();
if (count > 0)
return "";
return codPess;
}
}
catch (Exception ex)
{
return ex.Message;
}
}
First, I did search for this first and found this question answered: Previous Answer
The problem I have with this answer is that using this method causes a NullReferenceException. Obviously the code will still work with a try/catch block, but I had always understood that intentionally using an Exception as a means of controlling flow was poor design. Is there a better method of doing this?
To be clear as to the parameters, I am using OleDbConnection and OleDbCommand to read/write an Access 2010 database (.accdb format).
Below is the code I have currently using the above answer's approach:
public bool ReadAccessDb(string filePath, string queryString, bool hasRecords)
{
string connectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;" +
#"Data Source=" + filePath + ";" +
#"User Id=;Password=;";
using (OleDbConnection connection = new OleDbConnection(connectionString))
using (OleDbCommand command = new OleDbCommand(queryString, connection))
{
try
{
connection.Open();
int count = (int)command.ExecuteScalar();
//This works, but if no records exist it uses the Exception system to halt further action. Look for better approach.
if(count > 0)
{
hasRecords = true;
}
}
catch (System.Exception ex)
{
}
}
return hasRecords;
}
You can use :
int count = command.ExecuteScalar() is DBNull ? 0 : Convert.ToInt32(command.ExecuteScalar());
or use :
object obj = command.ExecuteScalar();
int count = obj is DBNull ? 0 : Convert.ToInt32(obj);
I'm posting this answer because the question is a bit ambiguous and the (currently) accepted answer can conceivably be "fooled" if a row exists but the first column returned by the SELECT statement happens to contain a NULL. Consider the test table
CREATE TABLE MyTable (ID COUNTER PRIMARY KEY, NullableColumn INTEGER NULL)
INSERT INTO MyTable (NullableColumn) VALUES (NULL)
which would look like
ID NullableColumn
-- --------------
1 <NULL>
If the SELECT statement used for testing was
string sql = "SELECT NullableColumn FROM MyTable WHERE ID=1";
then the method
static bool RecordExists(string queryString, OleDbConnection conn)
{
bool rtn;
using (var command = new OleDbCommand(queryString, conn))
{
object obj = command.ExecuteScalar();
int count = obj is DBNull ? 0 : Convert.ToInt32(obj);
rtn = (count != 0);
}
return rtn;
}
would return False, whereas this method
static bool RecordExists(string queryString, OleDbConnection conn)
{
bool rtn;
string rowCountString = String.Format("SELECT COUNT(*) AS n FROM ({0})", queryString);
using (var command = new OleDbCommand(rowCountString, conn))
{
int count = (int)command.ExecuteScalar();
rtn = (count != 0);
}
return rtn;
}
would return True.
I am trying to insert a Murmur3 hashed value into an nvarchar column.
This is my code:
public int createUserAccount(string email, string password)
{
try
{
using (SqlCommand com = new SqlCommand("[dbo].[CreateUserAccount]"))
{
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#email", email.Trim().ToLower());
int HashedPass = HashAlgorithms.Murmur3.Murmur3_1.Hash(
new System.IO.MemoryStream(Utility.GetBytes(password)));
com.Parameters.AddWithValue("#password", HashedPass.ToString());
com.Parameters.AddWithValue("#appId", appId);
return selectInt(com);
}
}
catch (Exception)
{
return -1;
}
}
int selectInt(SqlCommand com)
{
try
{
using (SqlConnection con = new SqlConnection(connectionString))
{
com.Connection = con;
con.Open();
object o = com.ExecuteScalar();
con.Close();
if (o != null)
{
return int.Parse(o.ToString());
}
else
{
return 0;
}
}
}
catch (Exception e)
{
throw e;
}
}
When I checked the value of password parameter that is passed through com object to selectInt() method, it's showing correct hashed value like -32xxxx.
But still I get this error:
Cannot insert the value NULL into column 'Password', table 'Accounts';
column does not allow nulls. INSERT fails. Line 17
Please tell me why this is happening?
It is a SQL error so check in your stored procedure because you are trying to insert null value in the 'Password' column.
Also check if your procedure has any triggers or if it is calling other procedures and if the insert is being made through the trigger or the called procedure.
Assuming that the cardDetailsID is 5.
Looking at record number 5 in the cardDetails table of the database, one can see that its other fields include "bgcolour" and "borderstyle". Therefore, for this particular record I've got cardDetailsID = 5, bgcolour = blue, bordersytle= solid.
I want to be able to get the bgcolour and bordersyle settings (blue and solid) from the cardDetailsID.
This is the code so far. The value in the querystring is working (number "5" is being passed) but now how do I get the rest of the setting of the row?
cardDetailsIDrv.Text = Request.QueryString["cardDetailsID"];
cardDetailsIDrv.Visible = false;
//create Connection
SqlConnection myConnection = new SqlConnection(ConfigurationManager.AppSettings["ConnString"]);
//create Command
SqlCommand getCardDetailsCMD = new SqlCommand("SELECT * FROM cardDetails WHERE cardDetailsID =" + Convert.ToInt32(cardDetailsIDrv.Text), myConnection);
myConnection.Open();
//create datareader
SqlDataReader myReader = getCardDetailsCMD.ExecuteReader();
//code works properly up till here
try
{
//Using DataReader to retrieve info from the database and display it on the panel
while (myReader.Read())
{
//I'm guessing here is where I'm messing things up
pnlCardps.BackColor = Color.FromName(myReader["bgcolour"].ToString());
pnlCardps.BorderStyle = (BorderStyle)Enum.Parse(typeof(BorderStyle), myReader["borderstyle"].ToString());
}
}
finally
{
if (myReader != null)
{
myReader.Close();
}
if (myConnection != null)
{
myConnection.Close();
}
}
PROBLEM SOLVED!!
All I had to do is tweak the code in the while loop to:
string bgColour = myReader["bgColour"].ToString();
pnlCardrv.BackColor = Color.FromName(bgColour);
string borderColour = myReader["borderColour"].ToString();
pnlCardrv.BorderColor = Color.FromName(borderColour);
firstly, you have to get the detailsID which is passed via the query string and then perform the query.
int id;
if(int.TryParse(Request.QueryString["detailsID"],out id))
{
string sql= string.Format("select .. from .. where id={0}",id);// using SqlParameter is much better and secure
// and execute your query and fetch the data reader
while(reader.Read())
{
// bla bla bla
}
}
Request.QueryString["detailsID"] will get you the value of the query string variable.
if (Request.QueryString("detailsID") == null || Request.QueryString("detailsID").Length <= 0 || !int.TryParse(Request.QueryString("detailsID"), out detailsID) || MessageThreadID <= 0)
{
//This is my standard exception, but you can handle it how you want.
throw new Exception("Error: unable to load detailsID. Request.QueryString.count: " + Request.QueryString.Count + " Request.QueryString(\"detailsID\"): " + Request.QueryString("detailsID"));
}