I've written a method which will try and delete a row from a db table based on a primary key id. The problem i have is that the try block is always returning "Success" even if a record has already been deleted / or it doesn't exist.
public string delete_visit(int id)
{
string deleteResponse = null;
string cnn = ConfigurationManager.ConnectionStrings[connname].ConnectionString;
using (SqlConnection connection = new SqlConnection(cnn))
{
string SQL = string.Empty;
SQL = "DELETE FROM [" + dbname + "].[dbo].[" + tbname + "] WHERE VisitorNumber = #IDNumber ";
using (SqlCommand command = new SqlCommand(SQL, connection))
{
command.Parameters.Add("#IDNumber", SqlDbType.Int);
command.Parameters["#IDNumber"].Value = id;
try
{
connection.Open();
command.ExecuteNonQuery();
deleteResponse = "Success";
}
catch (Exception ex)
{
deleteResponse = "There was a problem deleting the visit from the database. Error message: " + ex.Message;
}
}
}
return deleteResponse;
}
I want to be able to tell if the row was affected. I can do this in SQL Server Management Studio like so:
DELETE FROM Visits
WHERE VisitorNumber=88;
IF ##ROWCOUNT = 0
PRINT 'Warning: No rows were updated';
So i want to know how do i plug in the ##ROWCOUNT bit into my c# so that i can tell if the row was deleted?
thanks
ExecuteNonQuery() returns an int, indicating how many rows were affected.
So:
int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected == 0)
{
deleteResponse = "No rows affected";
}
The problem is that this number can be influenced based on what the query actually does. Executing triggers or calling stored procedures could mess with the output, changing the affected number of rows. If you really must, then first execute a query where you check that the record with the given ID exists.
Related
This question already has answers here:
Check if a record exists in the database
(13 answers)
Closed 4 months ago.
As of now, I can delete a record based on rank without checking if it exists, after that, it will pop up a message "Movie deleted" to notify the user.
protected void bn_delete_Click(object sender, EventArgs e)
{
string rank = tb_rank.Text;
string query = "SELECT * FROM MovieList WHERE Rank= #Rank";
new System.Data.OleDb.OleDbCommand(query, new System.Data.OleDb.OleDbConnection(connectionString));
System.Data.OleDb.OleDbCommand ocmd =
new System.Data.OleDb.OleDbCommand(query,
new System.Data.OleDb.OleDbConnection(connectionString));
ocmd.CommandType = CommandType.Text;
ocmd.CommandText = "DELETE FROM MovieList WHERE Rank= #Rank";
ocmd.Parameters.AddWithValue("#Rank", rank);
ocmd.Connection.Open();
ocmd.ExecuteNonQuery();
ocmd.Connection.Close();
string notification = "Movie deleted";
ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + notification + "');", true);
}
How can I make sure that the record exists first before deleting it?
If the record does not exist, I want to pop up a message showing "Movie not exists" and do nothing.
Thank you!
Instead of selecting and then deleting, you can use the fact that ExecuteNonQuery() returns an int that represents the number of rows effected by the SQL statement it executed. If it returns 0, it means that no record was deleted.
var rowsEffected = ocmd.ExecuteNonQuery();
var notification = rowsEffected == 0
? "Movie deleted"
: "Movie does not exist" ;
ExecuteNonQuery() returns the number of rows affected see. You could simply check if this integer is 0 and then return the message.
Besides using ExecuteNonQuery you can use ExecuteScalar. This executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored. The query can be a count and check if the count is larger than 0. Here is a snippet of how your code would look like:
void Main(string[] args)
{
string rank = tb_rank.Text;
if (!MovieExists(rank))
{
// show message
return;
}
DeleteMovie(rank);
}
private bool MovieExists(string rank)
{
string query = "SELECT COUNT(*) FROM MovieList WHERE Rank= #Rank";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(query);
command.Connection = connection;
command.Parameters.AddWithValue("#Rank", rank);
try
{
connection.Open();
if (Convert.ToInt32(command.ExecuteScalar()) > 0)
{
return true;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return false;
}
private void DeleteMovie(string rank)
{
string query = "DELETE FROM MovieList WHERE Rank= #Rank";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(query);
command.Connection = connection;
command.Parameters.AddWithValue("#Rank", rank);
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Developers, I am new to programming and c# coding I written a code to insert the Xml data into database and it is working perfect but my requirement in code is "if table is not exists create a new table with same columns in the DataBase and insert the data " so how can I write the code ?
public void SaveXmltoDB(List<MeterReading> MeterReadingList)
{
//OpenConnection();
// CreateTableIfNotExists();
foreach (var meterReading in MeterReadingList)
{
foreach(var interval in meterReading.IntervalDatalist)
{
foreach(var reading in interval.Readinglist)
{
string command = string.Format("insert into INTERVALDATA1(SerialNumber,TimeStamp,MeterData) VALUES ({0},'{1}',{2})", meterReading.MeterName, reading.TimeStamp.ToString(), reading.RawReading);
using (SqlConnection conn = new SqlConnection("server=LAPTOP-N6V52QKD\\AKHIL5656;" +
"Trusted_Connection=yes;" +
"database=ReportServer$AKHIL5656; " +
"connection timeout=30;" + "persist security info = True;" +
"Integrated Security = SSPI;"))
{
SqlCommand myCommand = new SqlCommand(command,conn);
myCommand.CommandType = System.Data.CommandType.Text;
conn.Open();
try
{
myCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
}
}
}
}
}
CloseConnection();
}
The above code is perfectly working to insert the data into my table ,In the above code how can I program If table not exists in the database create new table with same columns and insert the data?
can anyone help me on this?
Thanks,
I think this works for SQLServer and MYSQL:
Select * From Information_Schema.Tables Where Table_Name = 'TableName';
This returns all tables matching your name--1 row if the table exists, no rows if it doesn't.
I'm sure the fields returned can be reduced but since it's returning only one row I have never worried about it.
Here is summary of a code that I wrote yesterday with a few changes for the answer.
in the beginning the program checks if the table exist, using INFORMATION_SCHEMA.TABLES.
if the table is not exist it will be create with
createTableQuery field that represents the command for creating the new table. replace col1 col2 col 3... etc with your columns (SerialNumber,TimeStamp,MeterData... etc) replace the data types and use IDENTITY (1, 1) command if you need incremental value.
private void saveTableToDataBase()
{
string tableName = dbTableName;
// check if table exist in sql server db
if (IsTableExistInDb(tableName) == true) {
// table exist do something...
} else {
// create table, replace with your column names and data types
string createTableQuery = "CREATE TABLE " & "." & tableName & "(" & _
"ID int IDENTITY (1, 1) NOT NULL PRIMARY KEY, " & _
"Col1 int, " & _
"Col2 decimal(5,4), " & _
"Col3 int, " & _
"Col4 decimal(5,4), " & _
"Col5 int " & _
")"
// create table in database
Insert(createTableQuery);
}
}
public static Boolean IsTableExistInDb(string tableName)
{
Object result = ExecuteScalarWithAnonimusType("SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = " + "'" + tableName + "'", Con);
if (result != null && byte.Parse(result.ToString()) == 1)
{
return true;
}
else
{
return false;
}
}
public static object ExecuteScalarWithAnonimusType(string query)
{
Cmd = new SqlCommand(query, Con);
try
{
return Cmd.ExecuteScalar();
}
catch (Exception ex)
{
return null;
}
finally
{
if (Con.State != ConnectionState.Closed)
Con.Close(); Con.Close();
}
}
public static bool Insert(string command)
{
try {
con = new SqlConnection(System_Vars.SqlClientConnString);
con.Open();
cmd = new SqlCommand(command, con);
return cmd.ExecuteNonQuery();
} catch (Exception ex) {
return false;
} finally {
con.Close();
}
}
You don't want to try and do a create table from string SQL. I mean you could create stored procedure and then call it from code. But you probably want to do this during application setup program and not when the application runs.
I have written a unique ID generating function that generates a ID every time a new row is inserted into the database. But sometimes it gives same ID for every row. I can't find out what is the problem exactly happening that time. I give you the code for insert into database and code for ID generate. Please review the code and tell me if there is any logical error or not-
// Daily sales report entry codeing…………………………………………………………………………………………………………………
public string GetSalesTeam(SalesTeam st)
{
try
{
SqlConnection con = SqlConnDAC.CreateConn();
SqlCommand cmd = new SqlCommand("Insert into DSR values(#v1,#v2,#v3,#v4,#v5,#v6,#v7,#v8,#v9,#v10,#v11,#v12,#v13,#v14,#v15,#v16)", con);
IDGen.varr = DSR_IDGen(); //Calling id generate function
cmd.Parameters.AddWithValue("#v1", st.Sl_No);
cmd.Parameters.AddWithValue("#v2", st.User_ID);
cmd.Parameters.AddWithValue("#v3", st.Name);
cmd.Parameters.AddWithValue("#v4", st.Branch);
cmd.Parameters.AddWithValue("#v5", st.Desg);
cmd.Parameters.AddWithValue("#v6", st.Visiting_Date);
cmd.Parameters.AddWithValue("#v7", st.Name_Of_Client);
cmd.Parameters.AddWithValue("#v8", st.Address);
cmd.Parameters.AddWithValue("#v9", st.PhNo);
cmd.Parameters.AddWithValue("#v10",Convert.ToInt32(st.QuoteValue));
cmd.Parameters.AddWithValue("#v11", st.Remarks);
cmd.Parameters.AddWithValue("#v12", st.Source);
cmd.Parameters.AddWithValue("#v13",IDGen.varr);
cmd.Parameters.AddWithValue("#v14", st.Month);
cmd.Parameters.AddWithValue("#v15", st.Year);
cmd.Parameters.AddWithValue("#v16",Convert.ToInt32(st.ClosedValue));
// cmd.Parameters.AddWithValue("#v17", st.TypeOfCall);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
return "Success and DSR No.for_ "+st.Name_Of_Client+" = "+IDGen.varr+"";
}
catch (Exception e)
{
return e.ToString();
}
}
//ID generate function………………………………………………………..
public string DSR_IDGen()
{
int i = 0;
string temp;
string var;
var = ("DSR-" + i.ToString()).Trim();
SqlConnection conID = SqlConnDAC.CreateConn();
SqlCommand cmdd = new SqlCommand("select DSR_No from DSR", conID);
conID.Open();
SqlDataReader dr = cmdd.ExecuteReader();
while (dr.Read())
{
temp = (dr[0].ToString()).Trim();
if (var == temp)
{
i = i + 1;
var = ("DSR-" + i.ToString()).Trim();
continue;
}
}
dr.Close();
conID.Close();
return var;
}
// a static variable that holds the ID............................
public class IDGen
{
public static string varr;
}
One word of advice: don't try to make this any more difficult than it is, and don't try to outsmart SQL Server. Why don't you just use the database-provided mechanisms that's already in place for this: an IDENTITY column?
I would recommend you use:
an ID INT IDENTITY(1,1) column to get SQL Server to handle the automatic increment of your numeric value
a computed, persisted column to convert that numeric value to the value you need
So try this:
CREATE TABLE dbo.DSR
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
DsrID AS 'DSR-' + RIGHT('00000000' + CAST(ID AS VARCHAR(8)), 8) PERSISTED,
.... your other columns here....
)
Now, every time you insert a row into DSR without specifying values for ID or DsrID:
INSERT INTO dbo.DSR(Col1, Col2, ..., ColN)
VALUES (Val1, Val2, ....., ValN)
then SQL Server will automatically and safely increase your ID value, and DsrID will contain values like DSR-0000001, DSR-0000002,...... and so on - automatically, safely, reliably, no duplicates.
I ran into another issue again. I was trying to get data from the database using DataReader but I got the error when i was testing my code. Can anyone help me out? The error occurred at this line:
chkAssess = readAssess[columnName].ToString();
Below is the code snippet:
public string CheckAssess(string emailAddress, string columnName)
{
string chkAssess = "";
SqlDataReader readAssess;
//readAssess = new SqlDataReader();
string MgrAssessQry = "SELECT '"+columnName+"' FROM tblAllUsers";
//MgrAssessQry += " WHERE email ='" + emailAddress + "'";
SqlCommand cmdReadAssess = new SqlCommand(MgrAssessQry, cn);
cn.Open();
readAssess = cmdReadAssess.ExecuteReader();
while(readAssess.Read())
{
// Add the rows
chkAssess = readAssess[columnName].ToString();
}
return chkAssess;
}
try to use column name without ''
select something from table
instead of
select 'something' from table
for security reasons, don't create sql queries in that way (by concatenating strings) - use #parameters instead
2. close the reader at the end
Try this:
public string CheckAssess(string emailAddress, string columnName)
{
string chkAssess = "";
SqlDataReader readAssess;
//readAssess = new SqlDataReader();
string MgrAssessQry = "SELECT #Column_Name FROM tblAllUsers";
SqlCommand cmdReadAssess = new SqlCommand(MgrAssessQry, cn);
cmdReadAssess.Parameters.AddWithValue(new SqlParameter("Column_Name", columnName));
cn.Open();
readAssess = cmdReadAssess.ExecuteReader();
while(readAssess.Read())
{
// Add the rows
chkAssess = readAssess.GetString(0);
}
return chkAssess;
}
You have got several problems here.
Check whether your readAssess has rows like below.
if(readAssess.HasRows)
If it doesn't have rows then trying
chkAssess = readAssess.GetString(0);
would throw this error, as Arrays are index-based.
So your code should be like below
if(readAssess.HasRows)
{
while(readAssess.Read())
{
chkAssess = readAssess.GetString(0);
}
}
Other problem is you need to close both the reader & the connection afterwards.
readAssess.Close();
cn.Close();
Also your code is potentially vulnerable to SQL Injection.
if (reader.HasRows)
{
while (reader.Read())
{
int result = Convert.ToInt32(reader.GetString(0));
Console.WriteLine(result);
}
}
The most important thing is check the query first by executing in SQL Server and see if any result is coming or not.
Secondly based on the type of output you are receiving cast it to that particular data type (important).Mostly everyone is saving the data in varchar so.
I've been trying to get my query to work for some time it runs but doesn't insert anything nor does it return any errors.
The database connection is open and is successfuly connection.
The Table is called errorlog and holds the following data
- id (int autoincremental, Primary key, Unique)
- exception (varchar)
- time (DateTime)
exception = String(error message)
time = DateTime.Now
Here's the code:
public void insertError(string error, DateTime time)
{
SqlCeParameter[] sqlParams = new SqlCeParameter[]
{
new SqlCeParameter("#exception", error),
new SqlCeParameter("#time", time)
};
try
{
cmd = new SqlCeCommand();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO errorlog (exception, time) VALUES(#exception, #time)";
cmd.Parameters.AddRange(sqlParams);
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Any help would be appreciated, Thanks in advance.
EDIT
Removed quotes around #exception
Heres the connection:
protected DataController()
{
try
{
string appPath = System.IO.Path.GetDirectoryName(Assembly.GetAssembly(typeof(DataController)).CodeBase).Replace(#"file:\", "") + #"\";
string strCon = #"Data Source = " + appPath + #"Data\EasyShop.sdf";
connection = new SqlCeConnection(strCon);
}
catch (Exception e)
{
}
connection.Open();
}
Finally the way it gets called:
public bool log(string msg, bool timestamp = true)
{
DataController dc = DataController.Instance();
dc.insertError(msg, DateTime.Today);
return true;
}
Debug your application and see if connection points exactly to the
database you want. Also check if you look for the inserted records
in the same database.
If your connection belongs to the transaction, check if it's committed. You will not see those records inserted until transaction is committed.
It seems to me, that you INSERT is wrong. Remove quotes around #exception
Open SQL Server Profiler, connect to your database and check if your INSERT appears in there.