This is my code to display/search a record in a database table. How do I put a validation whether the roecord exists or not? It is searching through the ID of a member. how should I show a message if the record does not exist?
string connectionstring = "Server=Momal-PC\\MOMAL;Database=Project;Trusted_Connection=True;";
SqlConnection conn = new SqlConnection();
conn.ConnectionString = connectionstring;
conn.Open();
SqlDataAdapter sda = new SqlDataAdapter("Select * from Members where Number = '" + SearchID.Text + "'", conn);
DataTable dtStock = new DataTable();
sda.Fill(dtStock);
dataGridView1.DataSource = dtStock;
conn.Close();
if( 0 == dtStock.Rows.Count ) // does not exist
You can use like this:
If(dtStock.Rows.Count > 0) // If dtStock.Rows.Count == 0 then there is no rows exists.
{
// Your Logic
}
See Here & Here. How to use Dataset and DataTables.
You can use DataRowCollection.Count property.
Gets the total number of DataRow objects in this collection.
If(0 == dtStock.Rows.Count)
Console.WriteLine("There are no rows in that datatable")
You can do something like this
If(dtStock.Rows.Count > 0)
{
//code goes here
dataGridView1.DataSource = dtStock;
}
else
{
//Record not exists
}
This SQL will be likely be much faster, as it will only return 0 or 1 rows to the client, rather than every matching row and every single column. Get out of the habit of using *
SELECT 1 As X WHERE EXISTS (
Select 1 from Members where Number = '" + SearchID.Text + "')"
public static int RowCount()
{
string sqlConnectionString = #" Your connection string";
SqlConnection con = new SqlConnection(sqlConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("SELECT COUNT(*) AS Expr1 FROM Tablename", con);
int result = ((int)cmd.ExecuteScalar());
con.Close();
return result;
}
Related
I'm creating a simple web service to authenticate a user.
I have a problem filling the datatable(used to store the results of a select statement) properly, 'dt.rows.count' (dt is the name of the datatable) always returns 0 even if the select statement returns nothing. I've tried clearing the datatable before filling it, and after the if condition as well, but to no avail, I get the same result.
Would really appreciate any advice on how to proceed.
[WebMethod]
public string Authen(string a, string b)
{
var con = new SqlConnection("Data Source=SERVER-SQL;Initial Catalog=DECA-DB;Persist Security Info=True;User ID=sa;Password=*****");
var sda = new SqlDataAdapter("SELECT * FROM Login_Matrix WHERE Username = ' " + a + " ' AND Password = ' " + b + " '", con);
var dt = new DataTable();
con.Open();
dt.Clear();
sda.Fill(dt);
con.Close();
int x = dt.Rows.Count;
//return (x);
if ( x >0)
{
dt.Clear();
return ("In");
}
else
{
dt.Clear();
return ("out");
}
}
}
Adding a space after and before the single quotes makes your query search for inexistant user names and passords (like " Steve ") and it return no records
A quick fix could be
var sda = new SqlDataAdapter(#"SELECT * FROM Login_Matrix
WHERE Username = '" + a + "'
AND Password = '" + b + "'", con);
but this is very dangerous.
This code is vulnerable to Sql Injection attacks.
You should use parameters
var sda = new SqlDataAdapter(#"SELECT * FROM Login_Matrix
WHERE Username = #uname
AND Password = #pwd", con);
sda.SelectCommand.Parameters.Add("#uname", SqlDbType.NVarChar).Value = a;
sda.SelectCommand.Parameters.Add("#pwd", SqlDbType.NVarChar).Value = b;
And on the same line about security, another thing to consider as soon as possible, is that storing plain text password in your database is a really big security risk. You should search how to salt and store an hash of the password
There are other parts of this code to improve.
First you need to have using statements around the disposable objects
like the connection or the command.
Second, there is no need to have a full SqlDataAdapter and a
DataTable to just check if the user exists or not.
So you can rewrite your code as:
string cmdText = #"IF EXISTS(SELECT 1 FROM Login_Matrix
WHERE Username = #uname AND Password = #pwd)
SELECT 1 ELSE SELECT 0";
using(SqlConnection con = new SqlConnection("....."))
using(SqlCommand cmd = new SqlCommand(cmdText, con))
{
con.Open();
int result = (int)cmd.ExecuteScalar();
return ( result == 1 ? "In" : "out");
}
I am trying to print something if the number of rows returned is more than 0 based on a query:
using (SqlConnection con = new SqlConnection("ConnectionString")){
con.Open();
string query = "SELECT COUNT(*) FROM Some_Table WHERE Val > 5";
SqlCommand cmd = new SqlCommand(query, con);
cmd.ExecuteNonQuery(); // get the value of the count
if (count > 0)
{
Console.WriteLine("Returned more than 0 rows");
}
else
{
Console.WriteLine("Did not return more than 0 rows");
}
Console.ReadLine();
}
How can I find the number of rows returned?
Your query always return one row even no rows exists. It will return 0 if no rows exists for your WHERE condition
Use SqlCommand.ExecuteScalar Method ()
using (var con = new SqlConnection("ConnectionString"))
{
con.Open();
string query = "SELECT COUNT(*) FROM Some_Table WHERE Val > 5";
using (var cmd = new SqlCommand(query, con))
{
int rowsAmount = (int)cmd.ExecuteScalar(); // get the value of the count
if (rowsAmount > 0)
{
Console.WriteLine("Returned more than 0 rows");
}
else
{
Console.WriteLine("Did not return more than 0 rows");
}
Console.ReadLine();
}
ScalarValue will return first column of first row of query result. So for your query this is more effective method to retrieve information you need.
You can do this, Because ExecuteNonQuery - returns the number of rows affected.
int numberOfRecords = cmd.ExecuteNonQuery();
if (numberOfRecords > 0)
{
Console.WriteLine("Returned more than 0 rows");
}
else
{
Console.WriteLine("Did not return more than 0 rows");
}
The ExecuteScalar() method of the SQLClient Command object is specifically provided for returning single values from a query. It is more efficient in terms of code and performance.
using (SqlConnection conn = new SqlConnection("ConnectionString"))
{
conn.Open();
string query = "SELECT COUNT(*) FROM Some_Table WHERE Val > 5";
SqlCommand command = new SqlCommand(query, con);
Int32 count = (Int32) cmd.ExecuteScalar()
}
Use DataSet to get the count
SqlCommand cmd = new SqlCommand(query, con);
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataSet ds = new DataSet();
da.Fill(ds);
var count = ds.Tables[0].Rows.count;
I want that when SqlCommand returns zero result or null, then show alert message. I try but it always giving me
Object reference not set to an instance of an object.
Here is my code
ASPX.CS
public void gettable()
{
string user = Session["name"].ToString();
SqlConnection cnn = new SqlConnection("Data Source=LIFE_WELL;Initial Catalog=db_compiler;Integrated Security=True");
//string db = Session["value"].ToString();
string db = Session["value"].ToString();
SqlCommand cmd3 = new SqlCommand("SELECT Database_id from Create_db WHERE Database_Name='" + db + "'", cnn);
cnn.Open();
string dbid = cmd3.ExecuteScalar().ToString();
SqlCommand cmd4 = new SqlCommand("SELECT DISTINCT (Table_Name) from tbl_field WHERE Database_id=" + dbid + "", cnn);
string tbl_name = cmd4.ExecuteScalar().ToString();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd4);
da.Fill(dt);
if (dt.Rows.Count == 0)
{
Response.Write("<Script>alert('" + Server.HtmlEncode("No Tables Found") + "')</Script>");
}
else
{
foreach (DataRow dr in dt.Rows)
{
GridView1.DataSource = dt;
GridView1.DataBind();
cnn.Close();
}
}
}
try this
if (dt == null || dt.Rows.Count <= 0)
{
Response.Write("<Script>alert('No Tables Found')</Script>");
return;
}
also replace your code as
string tbl_name = Convert.ToString(cmd4.ExecuteScalar());
ExecuteScalar only returns one value. You have to make sure your query only returns that value.
use ExecuteReader
gives you a data reader back which will allow you to read all of the columns of the results a row at a time.
An example would be pulling profile information for one or more users.
SELECT * FROM pro WHERE id = '123456'
Here is my suggestions:
Data binding is one thing, display message is another. You should do data boning first, then display any message to users.
Do remember to close DB connection, or it will be a disaster.
I don't think you have to data binding in a loop, just do it one time.
You can refer "registerstartupscript" in MSDN.
I have two methods, one to insert, update and delete and a second is checking whether data already exists in my database or not. The main purpose of all code is that I don't want to insert duplicate data into the database.
public class DAL : System.Web.UI.Page
{
SqlConnection connection;
SqlCommand cmd;
SqlDataAdapter da;
DataTable dt;
string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
public int numofrows;
//Connection Method
public void Connection()
{
connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
connection.Open();
}
//This Method will Insert,Update and Delete in Database
public void InsertUpdateDelete(string query)
{
////connection = new SqlConnection("Data Source=IM-82B70624D72D;Initial Catalog=AppointmentScheduler;User ID=sa;Password=za3452432760za");
//connection = new SqlConnection(connectionString);
//connection.Open();
this.Connection();
cmd = new SqlCommand(query, connection);
numofrows = cmd.ExecuteNonQuery();
connection.Close();
}
//This Method will read data From Database
public DataTable ReadData(string Query)
{
this.Connection();
da = new SqlDataAdapter(Query, connection);
dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
Response.Redirect("Data already Exist");
}
return dt;
}
}
I have to use both above code in index.aspx. How can I use both above code in index.aspx?
I tried to use but that is not working.
index.aspx code:
protected void btnSaveDays_Click(object sender, EventArgs e)
{
this.query = "SELECT DaysName FROM Dayss WHERE Day_Id='" + DropDownListDays.SelectedValue + "'";
dal.ReadData(this.query);
this.query = "INSERT INTO Dayss VALUES ('" + DropDownListDays.SelectedItem.Text + "')";
dal.InsertUpdateDelete(this.query);
Response.Write("Day Inserted Successfully");
}
But this code is not working and generating error
Conversion failed
not Day_Id is int, and Dayss have two columns. One is id and second is
name
Then there is no point to use single quotes with int typed column value. Single quotes is for character column values.
this.query = "SELECT DaysName FROM Dayss WHERE Day_Id = " + DropDownListDays.SelectedValue ;
And if you want to insert just one column, you need specify your column name in your Dayss table like;
this.query = "INSERT INTO Dayss (YourColumnName) VALUES ('" + DropDownListDays.SelectedItem.Text + "')";
Take a look INSERT (Transact-SQL)
I've got a C# project where I'm trying to export the results of a datagrid. Sometimes the data gets quite large, so rather than re-executing the code I want to dump the dataset into a session variable.
This works perfectly in most of my projects. One example from a project where I use this is:
protected void Page_Load(object sender, EventArgs e)
{
SqlConnection sqlconnectionStatus = new SqlConnection(str);
string DDL_Value = Convert.ToString(Request.QueryString["DDL_Val"]);
//Use the ClassTesting class to determine if the dates are real, and fill in today's date if they're blank
string StDt_Value = ClassTesting.checkFields(Request.Form["txtStartDate"], "Date");
string EnDt_Value = ClassTesting.checkFields(Request.Form["txtEndDate"], "Date");
//string StDt_Value = Convert.ToString(Request.QueryString["StDt_Val"]);
//string EnDt_Value = Convert.ToString(Request.QueryString["EnDt_Val"]);
string BTN_Value;
// Because the date is stored as an INT, you have to request the string and then
// convert it to an INT
string StDT_Vals = Request.QueryString["StDt_Val"].ToString();
string EnDT_Vals = Request.QueryString["EnDt_Val"].ToString();
//sqlquery = "Select PROC_NM as 'Agent Name', AdminLevel as Role, Count(Claim_ID) as 'Count of Claims Reviewed', Spare as AgentID ";
//sqlquery = sqlquery + "from ClosedClaims_MERGE CCM ";
sqlquery = "Select PROC_NM as 'Agent Name', AdminLevel as Role, Count(DISTINCT Claim_ID) as 'Count of Claims Reviewed', Spare as AgentID ";
sqlquery = sqlquery + "from (SELECT DISTINCT Spare, SpareFinished, CLAIM_ID FROM ClosedClaims_MERGE ";
sqlquery = sqlquery + "UNION SELECT DISTINCT Spare, SpareFinished, CLAIM_ID FROM tblAuditing) CCM ";
sqlquery = sqlquery + "LEFT JOIN PROC_LIST PL ON CCM.Spare = PL.LOGIN ";
sqlquery = sqlquery + "WHERE CCM.SpareFinished >= '" + StDt_Value + "' AND CCM.SpareFinished <= '" + EnDt_Value + "' ";
sqlquery = sqlquery + "GROUP BY Spare, PROC_NM, AdminLevel ";
sqlquery = sqlquery + "ORDER BY Count(Claim_ID) DESC";
SqlConnection con = new SqlConnection(str);
SqlCommand cmd = new SqlCommand(sqlquery, con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
// Fill the DataSet.
DataSet ds = new DataSet();
adapter.Fill(ds, "dsEffVol");
// Add this to a session variable so the datagrid won't get NULLed out on repost
Session["SSEffVol"] = ds;
// Perform the binding.
grdEffVol.Attributes.Add("style", "overflow:auto");
//GridView_WODetails.Attributes.Add("style", "table-layout:fixed");
grdEffVol.AutoGenerateColumns = true;
grdEffVol.DataSource = ds;
grdEffVol.DataBind();
}
I've got a new project where I'm not using SQL strings, but instead I'm pulling data based on SQL Server Stored Procedures. The code block there is:
protected void btnSubmit_OnClick(object sender, EventArgs e)
{
List<ReportData> myReportData = new List<ReportData>();
using (SqlConnection connection1 = new SqlConnection(str2))
{
//Query the Reports table to find the record associated with the selected report
using (SqlCommand cmd = new SqlCommand("SELECT * from RM_tblManagerReports WHERE ReportID = " + cboFilterOption.SelectedValue + "", connection1))
{
connection1.Open();
using (SqlDataReader DT1 = cmd.ExecuteReader())
{
while (DT1.Read())
{
//Read the record into an "array", so you can find the SProc and View names
int MyRptID = Convert.ToInt32(DT1[0]);
string MyRptName = DT1[1].ToString();
string MyRptSproc = DT1[2].ToString();
string MySQLView = DT1[3].ToString();
string MyUseDates = DT1[4].ToString();
//Run the Stored Procedure first
SqlConnection connection2 = new SqlConnection(str2);
SqlCommand cmd2 = new SqlCommand();
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.CommandText = "" + MyRptSproc + "";
cmd2.Connection = connection2;
//Set up the parameters, if they exist
if (MyUseDates != "N")
{
cmd2.Parameters.Add("#StDate", SqlDbType.Date).Value = DateTime.Parse(txtStDate.Value);
cmd2.Parameters.Add("#EnDate", SqlDbType.Date).Value = DateTime.Parse(txtEnDate.Value);
}
else
{
}
try
{
connection2.Open();
GridView_Reports.EmptyDataText = "No Records Found";
SqlDataReader dr = cmd2.ExecuteReader(CommandBehavior.CloseConnection);
Session["SSRptMenu"] = dr;
GridView_Reports.DataSource = dr;
GridView_Reports.DataBind();
// Add this to a session variable so the datagrid won't get NULLed out on repost
GridView_Reports.DataBound += GridView_Reports_RowDataBound;
}
catch (Exception ex)
{
ScriptManager.RegisterStartupScript(btnSubmit, typeof(Button), "Report Menu", "alert('There is no View associated with this report.\\nPlease contact the developers and let them know of this issue.')", true);
Console.WriteLine(ex);
return;
}
finally
{
connection2.Close();
connection2.Dispose();
}
}
}
}
}
}
I'm kind of guessing my way through this, and I'm not sure if I'm reading the data into a dataset properly. The page is shutting down, and I'm pretty sure the problem is in the lines:
SqlDataReader dr = cmd2.ExecuteReader(CommandBehavior.CloseConnection);
Session["SSRptMenu"] = dr;
GridView_Reports.DataSource = dr;
Quite honestly, I've googled SqlDataReader vs SqlDataAdapter and can't really find anything, but I need to fill the session variable in the second example and also have the datagrid populate properly. So, in essence, I need to put the results of a Stored Procedure into a dataset. Can anyone offer suggestions on what I'm doing wrong?
I'm pretty sure most controls don't accept readers in their DataSource property. Plus the majority of readers are forward-only, so although you're trying to store the reader as a session variable, chances are you would only be able to read it once.
Why do you want to use a reader for this when your post seems to indicate that you know you need to use a DataSet? Why not just use an adapter the way you show in your first post? Adapters work fine with commands that use sprocs.
Instead of:
SqlDataReader dr = cmd2.ExecuteReader(CommandBehavior.CloseConnection);
Session["SSRptMenu"] = dr;
GridView_Reports.DataSource = dr;
Just use:
var adapter = new SqlDataAdapter(cmd2);
var ds = new DataSet();
adapter.Fill(ds, "MyTableName");
Session["SSRptMenu"] = ds;
GridView_Reports.DataSource = ds;