If not exists then insert else show message "Already exists" - c#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace Barcode
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string strconn = #"Data Source=ASHWINI-LAPY\SQLEXPRESS;Initial Catalog=complete;Integrated Security=True;Pooling=False";
SqlDataReader reader = null;
SqlConnection conn = null;
conn = new SqlConnection(strconn);
conn.Open();
DateTime Dt_Time = DateTime.Now;
string Barcode = textBox1.Text;
SqlCommand cmd = new SqlCommand("select Barcode from table3 where #Barcode='" + textBox1.Text + "'", conn);
cmd.Parameters.AddWithValue("#Barcode", textBox1.Text);
reader = cmd.ExecuteReader();
if (reader != null && reader.HasRows)
{
//email exists in db do something
MessageBox.Show("Barcode Already Exists!!");
}
else
{
string strquery = string.Format("insert into table3 values('{0}','{1}')", Barcode, Dt_Time);
cmd = new SqlCommand(strquery, conn);
int count = (int)cmd.ExecuteNonQuery();
MessageBox.Show("Barcode:" + Barcode +
"\nTime" + Dt_Time);
}
I am new to C# coding so I tried to do it like what I mentioned below in code, so please somebody help me.
I want to insert a barcode manually and when I press button the SQL Server database has to be checked whether that barcode exists. If not, it has to insert that barcode into the database, but if it already exists, it has to give a message that barcode already exists!
Along with inserting barcode I am also inserting system date and time also in database.

EDIT
C# code that you can write in your button click event
using (System.Data.SqlClient.SqlConnection cn =
new System.Data.SqlClient.SqlConnection(#"Data Source=ASHWINI-LAPY\SQLEXPRESS;Initial Catalog=complete;Integrated Security=True;Pooling=False"+
"Integrated Security=True"))
{
using (System.Data.SqlClient.SqlCommand cmd= new System.Data.SqlClient.SqlCommand("IsBarcodeCheckAndInsert", cn))
{
cmd.CommandType=CommandType.StoredProcedure ;
SqlParameter parm= new SqlParameter("#BarCode", cn",SqlDbType.VarChar) ;
parm.Value="ALFKI";
parm.Size=25;
parm.Direction =ParameterDirection.Input ;
cmd.Parameters.Add(parm);
SqlParameter parm2=new SqlParameter("#IsExists",SqlDbType.Int);
parm2.Direction=ParameterDirection.Output;
cmd.Parameters.Add(parm2);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
int IsExists = Convert.ToInt32(cmd.Parameters["#IsExists"].Value.ToString());
if(IsExists ==0)
MessageBox.Show("Barcode Already Exists !!");
else if(IsExists ==1)
MessageBox.Show("Barcode not Exists And Inserted In DataBase!!");
}
}
SQL Procdure
CREATE PROCEDURE [dbo].[IsBarcodeCheckAndInsert]
(
#BarCode AS VARCHAR(25),
#IsExists AS INT out )
AS
BEGIN
IF EXISTS (SELECT * FROM table3 WHERE BarCode = #BarCode )
BEGIN
set #IsExists =1
END
ELSE
BEGIN
Insert into table3 values(#BarCode ,getDate())
set #IsExists =0
END
END
Whats wrong with the code I check your code code is fine ..if it's not working at you end what error you are getting.
Just on recommandation make use of SQLParameter in your second queryi.e in insert query also to avoid SQLInjection attack for more detail check here : How does SQLParameter prevent SQL Injection?

Check out these lines of code:
string Barcode = textBox1.Text;
SqlCommand cmd = new SqlCommand("select Barcode from table3 where #Barcode='" + textBox1.Text + "'", conn);
cmd.Parameters.AddWithValue("#Barcode", textBox1.Text);
If textBox1.Text is equal to "example", the resulting SQL query would be
Select Barcode from table3 where 'example'='example'
You might want to change the SqlCommand statement to:
SqlCommand cmd = new SqlCommand("select Barcode from table3 where Barcode=#Barcode", conn);

You can do something like this:
SqlCommand cmd = new SqlCommand("select Barcode from table3 where Barcode=#Barcode", conn);
cmd.Parameters.AddWithValue("#Barcode", textBox1.Text);
Regards

You mixed up your sql parameters syntax, this:
SqlCommand cmd = new SqlCommand("select Barcode from table3 where #Barcode='" + textBox1.Text + "'", conn);
cmd.Parameters.AddWithValue("#Barcode", textBox1.Text);
Should be changed to be like this:
SqlCommand cmd = new SqlCommand("select Barcode from table3 where Barcode = #Barcode", conn);
cmd.Parameters.AddWithValue("#Barcode", textBox1.Text);
Basically you switched the column name with the parameter name in the query.
UPDATE
As for the "There is already an open DataReader..." exception, adjust the code with using blocks (in a "best practice" approach), like this:
private void button1_Click(object sender, EventArgs e)
{
string strconn = "<connection string";
using (SqlConnection conn = new SqlConnection(strconn))
{
bool readerHasRows = false; // <-- Initialize bool here for later use
DateTime Dt_Time = DateTime.Now;
string Barcode = textBox1.Text;
string commandQuery = "SELECT Barcode FROM table3 WHERE Barcode = #Barcode";
using(SqlCommand cmd = new SqlCommand(commandQuery, conn))
{
cmd.Parameters.AddWithValue("#Barcode", textBox1.Text);
using(SqlDataReader reader = cmd.ExecuteReader())
{
// bool initialized above is set here
readerHasRows = (reader != null && reader.HasRows);
}
}
if (readerHasRows)
{
//email exists in db do something
MessageBox.Show("Barcode Already Exists!!");
}
else
{
//Same as above
string strquery = "INSERT INTO table3 VALUES (#Barcode, #DtTime)"; // '{0}','{1}')", Barcode, Dt_Time);
using (SqlCommand cmd = new SqlCommand(strquery, conn))
{
cmd.Parameters.AddWithValue("Barcode", Barcode);
cmd.Parameters.AddWithValue("DtTime", Dt_Time);
int count = cmd.ExecuteNonQuery(); // this already the number of affected rows by itself
// NOTE: '\n' doesn't really work to output a line break.
// Environment.NewLine should be used.
MessageBox.Show("Barcode:" + Barcode + Environment.NewLine + "Time" + Dt_Time);
}
// code probably goes on ...
} // end of using(SqlConnection...
} // end of method
Should at least lead you on the right track.

You can do this in one sql query with the Merge-command.
In plain SQL it will look like:
merge table3 WITH(HOLDLOCK) as target
using (SELECT #Barcode, #DtTime)
as source (Barcode, DtTime)
on target.Barcode = #Barcode
when not matched then
insert ( Barcode, DtTime)
values ( #Barcode, #DtTime);

Related

how to print the last record of SQL server

I am having a database name "fees" where i am having 4 columns (admno, receiptnumber, name, tutionfee). Here primary key is "receiptnumber". I have entered several records with different admission number. There is also several entries with same admission number. Now i just want to print only last record which i have entered. How can i print. I have written a code but first record is printing.
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
con.Open();
string str;
str = "select * from fees where admno='" + temp + "'";
SqlCommand com = new SqlCommand(str, con);
SqlDataReader reader = com.ExecuteReader();
reader.Read();
TextBox1.Text = reader["admno"].ToString();
TextBox2.Text = reader["receiptnumber"].ToString();
TextBox3.Text = reader["name"].ToString();
TextBox4.Text = reader["tutionfee"].ToString();
This should do it. Add parameters to avoid sql injection!
You need to order by your ID DESCending and pick the fist one (TOP1)
string Command = "select TOP 1 * from fees where admno = #admno ORDER BY receiptnumber DSEC";
using (SqlConnection mConnection = new SqlConnection(ConnectionString))
{
mConnection.Open();
using (SqlCommand cmd = new SqlCommand(Command, mConnection))
{
cmd.Parameters.Add(new MySqlParameter("#admno", temp));
using (SqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
TextBox1.Text = reader["admno"].ToString();
TextBox2.Text = reader["receiptnumber"].ToString();
TextBox3.Text = reader["name"].ToString();
TextBox4.Text = reader["tutionfee"].ToString();
}
}
}
Assuming receiptnumber is an identity field, you would select top 1 * from fees order by receiptnumber desc

System.Data.SqlClient.SqlException: Incorrect syntax near the keyword 'file'

i'm new to AsP.net when i'm trying my usual code to connect to database there's exception keep shown and idon't know what's wrong
the exception is :
" System.Data.SqlClient.SqlException: Incorrect syntax near the keyword 'file'."
and this my code :
string ID = Request.QueryString["id"];
SqlCommand cmd = new SqlCommand("select title,file path,Upload Date from [Media] where ID=#id", conn);
cmd.CommandType = CommandType.Text;
SqlDataReader rdr=null;
try
{
conn.Open();
rdr = cmd.ExecuteReader();
try
{
conn.Open();
rdr = cmd.ExecuteReader();
// print the CustomerID of each record
while (rdr.Read())
{
pathTextBox.Text = rdr["file Path"].ToString();
DateTextBox.Text = rdr["Upload Date"].ToString();
titleTextBox.Text = rdr["title"].ToString();
}
Image1.ImageUrl = pathTextBox.Text;
}
if you have spaces in column names you need to use brackets like below
select title,[file path],[Upload Date] from [Media] where ID=#id
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "select title,[file path],[Upload Date] from [Media] where ID=#id";
cmd.Parameters.AddWithValue("#id", idval); // set the id parameter
using (var reader = cmd.ExecuteReader())
{
if (reader.Read()) // you don't need while loop
{
pathTextBox.Text = reader.GetString(reader.GetOrdinal("[file path]"))
}
}
}
If your column names contains white space (which is not recomended) you should use square brackets like []. For example, [Upload Date]
Column names must follow the rules for identifiers.
From Database Identifiers
SELECT *
FROM [My Table] --Identifier contains a space and uses a reserved keyword.
WHERE [order] = 10 --Identifier is a reserved keyword.
That's why you should use them like;
select title,[file path],[Upload Date]
Also you don't add your parameter value anywhere in your code.
SqlCommand cmd = new SqlCommand("select title,[file path],[Upload Date] from Media where ID=#id", conn);
cmd.Parameters.AddWithValue("#id", YourIDValue);
Also use using statement to dispose your SqlConnection and SqlCommand.
using (SqlConnection conn = new SqlConnection(YourConnectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
//Your code..
}
}

using the same instance of SQLCommand more than one time in the same code for more than one query?

I have question about using why i can not use the same instance of SQLCommand more than one time in the same code?
I tried the code down here and it runs good for the gridview but when i changed the query by using cmd.CommandText() method it keeps saying:
There is already an open DataReader associated with this Command which must be closed first.
This is the code:
string cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
SqlConnection con = new SqlConnection(cs);
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = "Select top 10 FirstName, LastName, Address, City, State from Customers";
GridView1.DataSource = cmd.ExecuteReader();
GridView1.DataBind();
cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
}
catch(Exception exp)
{
Response.Write(exp.Message);
}
finally
{
con.Close();
}
The problem is that you are using the SqlCommand object to generate a DataReader via the command.ExecuteReader() command. While that is open, you can't re-use the command.
This should work:
using (var reader = cmd.ExecuteReader())
{
GridView1.DataSource = reader;
GridView1.DataBind();
}
//now the DataReader is closed/disposed and can re-use command
cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
There is already an open DataReader associated with this Command which must be closed first.
This is the very reason you don't share a command. Somewhere in your code you did this:
cmd.ExecuteReader();
but you didn't leverage the using statement around the command because you wanted to share it. You can't do that. See, ExecuteReader leaves a connection to the server open while you read one row at a time; however that command is locked now because it's stateful at this point. The proper approach, always, is this:
using (SqlConnection c = new SqlConnection(cString))
{
using (SqlCommand cmd = new SqlCommand(sql, c))
{
// inside of here you can use ExecuteReader
using (SqlDataReader rdr = cmd.ExecuteReader())
{
// use the reader
}
}
}
These are unmanaged resources and need to be handled with care. That's why wrapping them with the using is imperative.
Do not share these objects. Build them, open them, use them, and dispose them.
By leveraging the using you will never have to worry about getting these objects closed and disposed.
Your code, written a little differently:
var cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
var gridSql = "Select top 10 FirstName, LastName, Address, City, State from Customers";
var cntSql = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
try
{
using (SqlCommand cmd = new SqlCommand(gridSql, con))
{
GridView1.DataSource = cmd.ExecuteReader();
GridView1.DataBind();
}
using (SqlCommand cmd = new SqlCommand(cntSql, con))
{
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
}
}
catch(Exception exp)
{
Response.Write(exp.Message);
}
}
Thank u quys but for the guys who where talking about using block !
why this code work fine which i seen it on example on a video ! It's the same thing using the same instance of SqlCommand and passing diffrent queries by using the method CommanText with the same instance of SqlCommand and it's execute just fine , this is the code :
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = "Delete from tbleProduct where ProductID= 4";
int TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
cmd.CommandText = "Insert into tbleProduct values (4, 'Calculator', 100, 230)";
TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
cmd.CommandText = "ypdate tbleProduct set QtyAvailbe = 234 where ProductID = 2";
TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
}

C# project runs with no errors but doesn't add anything in the database?

I am trying to add records into my C# project and it runs with no errors but it doesn't add anything in the database:
private void saveBtn_Click(object sender, EventArgs e)
{
if (admNo.Text != "" & session.Text != "" & name.Text != "")
{
SqlConnection cn = new SqlConnection("Data Source=C:\\Users\\Divya Pathak\\Documents\\Visual Studio 2012\\Projects\\SchoolRecord\\SchoolRecord\\Database1.sdf");
SqlCommand cmd = new SqlCommand();
cn.Open();
cmd.CommandText = "insert into addNew (no,session,name) values ('" + admNo.Text + "', '" + session.Text + "', '" + name.Text + "')";
cmd.ExecuteNonQuery();
cn.Close();
MessageBox.Show("Record inserted successfully", "mission successfull");
}
}
Could someone please advise why?
you need to set cm.Connection as cn
cm.Connection =cn;
OR
using (var cn = new SqlCeConnection("connection string"))
using (var cmd = new SqlCeCommand("insert addNew (no,session,name) values (#no,#session,#name)", cn))
{
cmd.Parameters.AddWithValue("#no", admNo.Text);
cmd.Parameters.AddWithValue("#session", session.Text);
cmd.Parameters.AddWithValue("#name", name.Text);
cn.Open();
cmd.ExecuteNonQuery();
}
This will help you to write the correct connection string for SQL CE
You have four mistakes:
You never associate the connection with the command
You're connecting to a Sql Server Compact database using the full Sql Server provider (you should be using the SqlCe namespace:
You're building your query using unsafe string concatenation instead of query parameters. Fix this!
Your connection won't be closed if an exception is thrown, which can ultimately lock you out of your database. You need to close the connection as part of a finally block, and the easiest way to do this is with a using block.
.
using (var cn = new SqlCeConnection("connection string here"))
using (var cmd = new SqlCeCommand("insert into addNew (no,session,name) values (#no,#session,#name)", cn))
{
//guessing at column lengths:
cmd.Parameters.Add("#no", SqlDbType.Int).Value = int.Parse(admNo.Text);
cmd.Parameters.Add("#session", SqlDbType.NVarChar, 100).Value = session.Text;
cmd.Parameters.Add("#name", SqlDbType.NVarChar, 60).Value = name.Text;
cn.Open();
cmd.ExecuteNonQuery();
}

SqlDataReader Execution error

i m trying to retrieve the Specialization ID from a table called Specializationtbl, using C# MSVS 2008 and the table includes SpecializationName and SpecializationID beside some other rows and my question is related to some error " No Data to present ", the command goes as bellow:
SqlCommand READSpecID = new SqlCommand("SELECT * FROM Specializationtbl WHERE SpecializationName='" + comboBox1.Text + "'" , DBcnction);
DBcnction.Open();
SqlDataReader ReadSpecID_ = READSpecID.ExecuteReader();
ReadSpecID_.Read();
int SpecID_ = Convert.ToInt16(ReadSpecID_["SpecID"].ToString());
DBcnction.Close();
i also tried to Select the "SpecID" instead of all the rows, but cant seem to seal the query correctly and keep receiving "No data present " error, any idea where am i making the mistake?
1) Try opening DBcnction before assigning the value to READSPecID
DBcnction.Open();
SqlCommand READSpecID = new SqlCommand("SELECT * FROM Specializationtbl WHERE SpecializationName='" + comboBox1.Text + "'" , DBcnction);
2) Run the command in SSMS:
SELECT * FROM Specializationtbl WHERE SpecializationName ='yourvalue'
and see if any results are returned
3) Check comboBox1.Text has a value in it
4) Validate the contents of comboBox1.Text (Or use paremetrised queries or a stored procedure) to ensure you do not become a victim of SQL Injection: http://en.wikipedia.org/wiki/SQL_injection
Refactor to solve your TWO problems:
Your SQL injection problem when building your SQL statement.
Use ExecuteScalar if you only need one value.
Implement using blocks.
string retVal;
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT SpecID FROM Specializationtbl WHERE SpecializationName= #Name";
cmd.Parameters.AddWithValue("#Name", comboBox1.Text);
conn.Open();
retVal = cmd.ExecuteScalar().ToString();
}
int specID = int.Parse(retVal);
If you really needed more than one value from your statement:
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT SpecID, Value2 FROM Specializationtbl WHERE SpecializationName= #Name";
cmd.Parameters.AddWithValue("#Name", comboBox1.Text);
conn.Open();
var dr = cmd.ExecuteReader();
while (dr.Read())
{
Customer c = new Customer {
ID = dr["SpecID"].ToString(),
Value = dr["Value2"].ToString(),
};
}
}
Need to first test if there are any rows. I suspect the query is returning zero rows.
if (ReadSpecID_.HasRows)
{
ReadSpecID_.Read();
}

Categories

Resources