I have a login page, users have ID's and ID is the primary key in the table. I also have an admin account, and admin can create users. But when i create a user account with an existing ID, the web page crashes. I want to handle this situation and give a warning indicating that this ID exists and cannot be created. Here is my code:
public void CreateStudent(int ID, String status, String email, String firstName, String lastName, String password, String level, String program)
{
SqlConnection con = new SqlConnection(GetConnectionString());
string query1 = "insert into StudentTable(Name,Surname,ID,email,level,program,status,password,Type) values(#firstName,#lastName,#ID,#email,#level,#program,#status,#password,'Student')";
SqlCommand command = new SqlCommand(query1,con);
command.Parameters.AddWithValue("#firstName", firstName);
command.Parameters.AddWithValue("#lastName", lastName);
command.Parameters.AddWithValue("#ID", ID);
command.Parameters.AddWithValue("#email", email);
command.Parameters.AddWithValue("#level", level);
command.Parameters.AddWithValue("#program", program);
command.Parameters.AddWithValue("#status", status);
command.Parameters.AddWithValue("#password", password);
int result;
con.Open();
result = command.ExecuteNonQuery();
con.Close();
}
Can anyone help me with this? Thanls
There are multiple ways. You could catch an Exception and display an error message. That will also help in other error scenario's, like a lost connection.
However, if it's a situation you expect to occur during normal operation, you should handle the situation without an Exception. One way to do that is to have your insert only insert a row with a new id:
insert YourTable
(id, col1, col2, ...)
select #id
, #col1
, #col2
, ...
where not exists
(
select *
from YourTable
where id = #id
)
Pass parameters to your query like:
command.Parameters.AddWithValue("#id", 42);
command.Parameters.AddWithValue("#col1", "value1");
command.Parameters.AddWithValue("#col2", "value2");
Now ExecuteNonQuery() returns the number of affected rows. You can use that to check if the insert actually added a new row to the table:
var result = command.ExecuteNonQuery();
if (result == 1)
{
lblResult.Text = "New row inserted!";
lblResult.Color = Color.Green;
}
else
{
lblResult.Text = "Failed to insert new row.";
lblResult.Color = Color.Red;
}
Rather than tying to handle the error that comes back from attempting to add a user with the same ID, it would be better to check for the user's existence first and only create the new account if you can. Though you still need to handle the exception to cater for the case where two people try to create the same record.
So you'd have the following SQL:
select * from StudentTable where ID = #newID
and if this found a record you could report the error. If it doesn't find anything then you can go ahead and create the new record.
Though if you are using the ID as the primary key it would be better to have that as an Identity column on the table and have it auto-increment when you create a new row. You'd still have to check to see if the student already exists - use the e-mail as the human readable uniqueness condition.
If you add uniqueness constraint on the e-mail column then you'll be able to trap the case of two people trying to create the same record.
I have made the e-mail attribute as a primary key and then checked the database whether same e-mail exists and that worked
Related
I have tried to implement login page in ASP.NET Core MVC and using postgresql as database.
It should check whether user exits in the database table of postgresql and verify, so what is the query to search for user in database and made them sign in?
I have written my code like this:
public IActionResult Login(string seller_email, string seller_password)
{
using var connection = new NpgsqlConnection(connString);
connection.Open();
string main_query = String.Format(#"select exists(select 1 from public.""sellers"" where ""seller_email""='{0}')", seller_email);
using var command_main = new NpgsqlCommand(main_query, connection);
int result_main = command_main.ExecuteNonQuery();
if (result_main < 0)
{
return View(nameof(Create));
}
else
{
return View(nameof(Sign));
}
}
There is a seller table in the database, so just have to check seller exists or not - if exists the have to create a view for it
You are doing a select query, so you must use a command.ExecuteReader.
The ExecuteNonQuery is to be used with statements that update/insert/delete records.
BUT, most importantly, don't concatenate user submitted values into the query string, as it opens the door to SQL injections. Instead, used a parameter.
See the getting started doc for a simple example.
I am moving my datamodel to Azure Elastic Scale.
After some testing and some experiences I fall in love if it, it is simple and with that kind of approach the code remains clean and easy to maintain.
I just have one big question, where is the Sharding key defined? I cannot find info on the sample downloaded from Visual Studio and I can beat that this is a straight forward answer.
In the sample offered by Microsoft the default sharding key is CustomerId but i cannot find where the reference to that key takes place.
Could it be in ShardMapName from configuration file?
Thanks in advance.
There is no explicit link between the the sharding key in the SQL schema and its usage (in code).
So in the Getting Started sample, the Customers and Orders table both contain a CustomerId column, and you can see that in DataDependentRoutingSample.cs when we access these tables we make sure to provide the same customerId value to the shardMap.OpenConnectionForKey method that we then use for customerId column (both in the SELECT and INSERT statements) in the following query.
// Looks up the key in the shard map and opens a connection to the shard
using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString))
{
// Create a simple command that will insert or update the customer information
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = #"
IF EXISTS (SELECT 1 FROM Customers WHERE CustomerId = #customerId)
UPDATE Customers
SET Name = #name, RegionId = #regionId
WHERE CustomerId = #customerId
ELSE
INSERT INTO Customers (CustomerId, Name, RegionId)
VALUES (#customerId, #name, #regionId)";
cmd.Parameters.AddWithValue("#customerId", customerId);
cmd.Parameters.AddWithValue("#name", name);
cmd.Parameters.AddWithValue("#regionId", regionId);
cmd.CommandTimeout = 60;
// Execute the command
cmd.ExecuteNonQuery();
}
In other words, when you provide a certain key value in the OpenConnectionForKey call, it's your responsibility to make sure that all SQL queries with that connection are restricted to that key value, otherwise you may end up with incorrect results (e.g. if it was a SELECT query) or rows living on the wrong shard (e.g. if it was an INSERT query).
It's possible to fix this safety issue by using the new Row-Level Security feature. We have a sample called Entity Framework Multi-Tenant Shards that demonstrates how to combine Shard Maps with Row-Level Security. The relevant code is in ElasticScaleContext.cs:
SqlConnection conn = null;
try
{
// Ask shard map to broker a validated connection for the given key
conn = shardMap.OpenConnectionForKey(shardingKey, connectionStr, ConnectionOptions.Validate);
// Set CONTEXT_INFO to shardingKey to enable Row-Level Security filtering
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = #"SET CONTEXT_INFO #shardingKey";
cmd.Parameters.AddWithValue("#shardingKey", shardingKey);
cmd.ExecuteNonQuery();
return conn;
}
catch (Exception)
{
if (conn != null)
{
conn.Dispose();
}
throw;
}
Thanks for your great question!
I am designing a web-based logistics system using ASP.NET and SQL Server.
In one of my classes when I try to insert data to database, there is a violation of primary key error, but data inserts successfully into the table. I can not find out where the problem is. Can anyone see what I am doing wrong?
public int fillShipmentDetail()
{
int success = 0;
string connectionString = ConfigurationManager.ConnectionStrings["LGDB"].ToString();
SqlConnection sqlCon = new SqlConnection(connectionString);
SqlCommand sqlCom = new SqlCommand("fillShipmentDetails", sqlCon);
sqlCom.CommandType = CommandType.StoredProcedure;
sqlCon.Open();
sqlCom.Parameters.AddWithValue("shipOrderID", ShipOrderID);
sqlCom.Parameters.AddWithValue("totalWeight", TotalWeight);
sqlCom.Parameters.AddWithValue("weightIsMetric", WeightUnit);
sqlCom.Parameters.AddWithValue("weightIsImperial", VolumeUnit);
sqlCom.Parameters.AddWithValue("volume", Volume);
sqlCom.Parameters.AddWithValue("quantity", Quantity);
sqlCom.Parameters.AddWithValue("value", Value);
sqlCom.Parameters.AddWithValue("description", GoodsDescription);
success = sqlCom.ExecuteNonQuery();
if (success == 1)
{
success = 1;
}
else
{
success = 0;
}
sqlCon.Close();
return success;
}
aspx.cs page
Classes.ShipmentDetails fillShipmentDetails = new Classes.ShipmentDetails(
getLastShipOrder, _weight, _checkMetricImperial_weight, _checkMetricImperial_volume,
_volume, _quantity, _value, txtGoodsDescription.Text);
int success3 = fillShipmentDetails.fillShipmentDetail();
As you can see in the below picture the record shipOrderID 7192 is already inserted into the table.
I have deleted all three tables , and insert new data. although data inserts successfully but error happens again.
this screenshot shows everything clearly , by every new insertion into database there is a primary key error on last table , as you can see there is not any duplicate key and data inserted successfully.
looks like fillShipmentDetails.fillShipmentDetail() is getting fired twice. Put a Breakpoint in the code and check
shipOrderId already exists in your table.
You need to give it a new unique value. The reason why the table updates is because the shipOrderId already exists, so you can create a new Shipping Order with the Id, however that order is not referring to the correct shipOrderId
I am using ASP.NET 4.0 with SQL Server 2008 R2 and PetaPoco ORM.
A Web Form consists of Tab Panels, for example:
-- Employee General Information
-- Appointment
-- Education
Each Tab Panel entry goes to a specific table in SQL Server. I have a main table, employee, with Primary Key empID. Other tables, viz., appointment, education etc. are related with empID.
I have multiple methods to Save record in respective tables:
AddGeneralInformation saves the General Information Tab Panel record.
AddAppointment saves the appointment details and so on.
The application is being used in a concurrent environment where multiple users are either inserting or updating records.
For the second and third methods to insert a new record, the methods must have the correct empID. As soon as the first method (General Information) saves the record, the empID is to be used in other methods.
The problem is that if I use:
Select max(empID)
then it won't pick the correct empID as many users are inserting records.
On solution I feel is to use another column containing SessionID and use this query:
Select max(empID) where sessionID = SessionID
Is there any more reliable way to do this?
** Edited **
protected void btnSave_Click(object sender, EventArgs e)
{
Session.Add("TaskFlag", "New");
AddUpdateEmployee();
AddUpdateAddress();
}
protected void AddUpdateEmployee()
{
var db = new PetaPoco.Database("cnWeb");
var emp = new employee(); */
using (TransactionScope scope = new TransactionScope())
{
db.BeginTransaction();
emp.deptcode = txtEmpCode.Text.TrimEnd();
emp.empname = txtEmpName.Text.TrimEnd();
emp.guardianname = txtGuardian.Text.TrimEnd();
emp.relationwithemployee = ddlRelation.Text.TrimEnd();
emp.gender = ddlGender.SelectedItem.Text;
emp.dateofbirth = Convert.ToDateTime(txtDOB.Text.TrimEnd());
if (Session["TaskFlag"].ToString() == "New")
db.Insert(emp);
else if (Session["TaskFlag"].ToString() == "Update")
db.Update<employee>("SELECT * FROM employee WHERE empid = #0", Session["EmployeeID"]);
reuse.CustomClientMessage("Record Saved", this.Page);
ClearFields();
/* Commit Transaction */
db.CompleteTransaction();
scope.Complete();
}
}
protected void AddUpdateAddress()
{
var db = new PetaPoco.Database("cnWeb");
var addr = new emp_address();
using (TransactionScope scope = new TransactionScope())
{
db.BeginTransaction();
/* Permanaent Address */
addr.perm_houseno = txtPermHouse.Text.TrimEnd();
addr.perm_street = txtPermStreet.Text.TrimEnd();
addr.perm_place = txtPermCity.Text.TrimEnd();
addr.perm_pincode = txtPermPincode.Text.TrimEnd();
addr.perm_landlinephone = txtPermLandline.Text.TrimEnd();
addr.perm_mobilephone = txtPermMobile.Text.TrimEnd();
if (Session["TaskFlag"].ToString() == "New")
db.Insert(addr);
else if (Session["TaskFlag"].ToString() == "Update")
db.Update<emp_address>("SELECT * FROM emp_address WHERE empid = #0", Session["EmployeeID"]);
/* Commit Transaction */
db.CompleteTransaction();
scope.Complete();
}
}
Best solution: make your EmpID column an INT IDENTITY in SQL Server and let the database handle the details.
Anything you dream up in code (T-SQL or C#) is most likely going to have some issues and won't work well under load - why not just use what's there, works, and is tested by hundreds of thousands of users?
Once you insert a row into a table with an INT IDENTITY column, you can fetch that value using
DECLARE #NewEmpID INT
SELECT #NewEmpID = SCOPE_IDENTITY()
or alternatively, you could use the OUTPUT clause on your INSERT statement
INSERT INTO dbo.YourTableHere(List of columns)
OUTPUT Inserted.EmpID
VALUES(list of value here)
create a new column like created_datewith datetime in the table Employee General Information and get the latest record.
Try this Procedure
create Procedure Get_LastRow
(
-- Table name to retrieve last record
#Tname Varchar(50)
)
AS
BEGIN
EXECUTE ('DECLARE GETLAST CURSOR DYNAMIC FOR SELECT * FROM ' + #Tname)
OPEN GETLAST
FETCH LAST FROM GETLAST
CLOSE GETLAST
DEALLOCATE GETLAST
END
Execute the procedure like this.
EXEC Get_LastRow 'dbo.TableA'
Just after the Insert query, you the SELECT ##IDENTITY. You field EmpID need to be a IDENTITY TO work.
I am very new to linq to sql and I am not sure how to actually delete a record.
So I been looking at this tutorial
http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx
So for Update they have
NorthwindDataContext db = new NorthwindDataContext();
Product product = db.Products.Single(p => p.ProductName == "Toy 1");
product.UnitPrice == 99;
product.UnitsInStock = 5;
db.SubmitChanges();
For delete they have
NorthwindDataContext db = new NorthwindDataContext();
var toyProducts = from p in db.Producsts
where p.ProductName.Contains("Toy")
select p;
db.Products.RemoveAll(toyProducts);
db.SubmitChanges();
So do I have to query every time, to get the record in order to delete that record? Like I can sort of see doing this with update since you need to give it a record which to update first and then make the changes so I understand the querying part but not with delete.
Like can't you just send in what you want to delete and it goes and deletes it? why do you have to first get it and then tell it to be deleted?
Is that not 2 hits on the database?
Also I have foreign key relationship that I am trying to get to work. So I have this
public ViewResult(string param1, string param2)
{
Table A = new Table A
A.Field1 = param1;
A.Field2 = param2;
Delete(A);
}
private void Delete(Table A)
{
DbContext.A.DeleteAllOnsubmit(A.TableB);
DbContext.A.DeleteAllOnSubmit(A.TableC);
DbContext.A.DeleteOnSubmit(A);
}
So this fails it comes up with this message "Cannot remove an entity that has not been attached."
So I can see why the first 2 lines would fail in the delete method, since I made a new object and their is nothing in the object that has any information about TableB and TableC.
I however can't see why the last line still fails even if the 2 other lines where not there.
Like how I thought it would work it would take my Table A class object that I passed in and look through the table for that information contained in it. It does not seem to be the case though.
So do I first have to take the information out and then do a query to get it and then delete it, like in the example?
Also what is the difference between removeAll() and say DeleteAllOnSubmit().
Like I said I am new to linq to sql and have not been able to sit down and read a book on it due to time constraints. Once I have more time I will read through a book probably.
Thanks
You have several questions in your one question, but I will start with the simplest, about attaching, if you already have the primary key. If you don't have the primary key then I have always just done a fetch then a delete, but, whenever I do a fetch I tend to store the primary key for updates and deletes.
It will delete off of the primary key, but if you have that then just attach as I do below and call delete. I don't pass around the object needed by DLINQ as I want to be able to change it if I want, so I pass in a different User object and just pull the PK from the business class and put it into the DAO class.
var db = new MeatRequestDataContext();
if (input.UserID > 0)
{
entity = new User()
{
UserID = input.UserID
};
db.Users.Attach(entity);
db.Users.DeleteOnSubmit(entity);
}
this is a simple way to delete row from table by linq query.may be it helps .
var summary_delete = database.summeries.Find(id);
var delete = database.summeries.Remove(summary_delete);
database.SaveChanges();
reference : http://mvc4asp.blogspot.in/2013/09/how-to-delete-table-row-in-sql-database.html
Inserted_LINQDataContext db = new Inserted_LINQDataContext();
Item itm = new Item();
int ID = Convert.ToInt32(TextBox1.Text);
var DeleteID = from d in db.Items
where d.id == ID
select d;
db.Items.DeleteAllOnSubmit(DeleteID);
db.SubmitChanges();
Label2.Text = "Record deleted Successfully.";
TextBox1.Text = "";
where Item is Table name, Linserted_LINQDataContext is your Linq DB name, id is the Column name in Item table. Items is the alias name of Item table in linq.
SupportDataDataContext Retrive = new SupportDataDataContext();
// SupportDataDataContext delete = new SupportDataDataContext();
Topic res = Retrive.GetTable<Topic>().Single(t => t.ID == topicID);
if (res != null)
{
Retrive.Topics.DeleteOnSubmit(res);
Retrive.SubmitChanges(ConflictMode.ContinueOnConflict);
}
I know the question is old but this may be useful to someone:
"YourDataContext" dc = new "yourDataContext";
"YourTable" element = dc."YourTable".First(a => a.Id == 12345);
dc."YourTable".DeleteOnSubmit(element);
dc.SubmitChanges();