Deleting multiple tables from SQL Server 2008 using Datalist C# - c#

This may seem a common question but I googled to find the right answer that can fix my problem and failed to do so.
I have multiple tables connected to each other by ProductID and I wish to delete all data from them when the product from main table has been deleted. i.e.
Products : ProductID - Vender - Description
ProductRatings : ProductID - Rating - VisitorsCount
ProductComments : ProductID - VisitorName - Comment
I read that for such situation a SQL trigger is used but I have no idea about it besides I might be mentioning my DataSource in ASCX.CS file in some cases and in some cases I might simply use SqlDatasoruce in ASCX file. Is there any query or stored procedure that can be used?

The easiest way to do this is to implement a foreign key relationship to ProductID and set on delete cascade. This is a general idea:
create table ProductRatings
(
ProductID int not null
foreign key references Products(ProductID) on delete cascade,
Rating int not null,
VisitorsCount int not null
)
What that does is when you delete a primary key value from the Products table, that causes SQL Server to delete all records that have a foreign key constraint to that primary key value. If you do this with your ProductComments table as well, problem solved. No need to explicitly call a DELETE on any records in the referencing tables.
And if you aren't using referential integrity...you should.
EDIT: this also holds true for UPDATEs on the primary key. You just need to specify on update cascade, and the foreign key references will update as the primary key did to ensure RI.

Related

create table that is many to many between 2 tables in different databases

So i have 2 databases. DB1 and DB2. My 'discountCode' table is in DB1 and my 'AspnetUser' table is in DB2. I want to do a many to many table in DB1 between 'discountCode' table and 'AspnetUser' table so i can se that a user already have used a specific discountcode so the user cant use it twice.
I tried doing a normal many to many table between them and it went like this:
CREATE TABLE [dbo].[DiscountUser] (
[DiscountId] INT NOT NULL,
[UserId] nvarchar(128) NOT NULL,
[LanguageId] INT NOT NULL,
CONSTRAINT [PK_DiscountUser] PRIMARY KEY CLUSTERED ([DiscountId] ASC, [UserId] ASC),
CONSTRAINT [FK_DiscountUser_Discount_DiscountId] FOREIGN KEY ([DiscountId]) REFERENCES [dbo].[DiscountCode] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_DiscountUser_AspNetUsers_Id] FOREIGN KEY ([UserId]) REFERENCES [db2].dbo.[AspNetUsers] ([id]) ON DELETE CASCADE,
CONSTRAINT [FK_DiscountUser_Language] FOREIGN KEY ([LanguageId]) REFERENCES [dbo].[Language] ([Id])
I then want to update my entity framework modeldesign so i can include this new many to many table in my c# project. So it is important that however i fix this problem i will still be able to use this many to many table like any other entity i have.
First i thought that i would put all the tables in the same database untill i asked about this problem to a friend. My friend did not have much time. All he said to me was do a join in your c# code to bring the 2 tables together. Just ask stackoverflow and they will help you how. So here i am. How do i do a join in m y c# code or is there maybe a better way to get around my problem?
You can't have foreign keys between databases - the error is pretty clear about that. But you can still join them together in a query, you just won't get protection that having them joined by a foreign key gives (e.g. without a foreign key, you can end up with orphaned entries with no data in the foreign table).
If you can have them in a single database that would be best.

Error 1215: Cannot add foreign key constraint MySQL Error

Im making an Order table in which paintings_id and customer_id act as foreign keys and they correspond to customers_id and painting_id which act as primary keys in their respective tables. They have the same datatype that is Int. I have searched for this error but cannot find any possible solution.
use artgallery;
CREATE TABLE item_order(
order_id INT UNIQUE NOT NULL auto_increment,
customer_id INT UNIQUE NOT NULL ,
paintings_id INT UNIQUE NOT NULL ,
primary key(order_id),
FOREIGN KEY (customer_id) REFERENCES customers(customers_id),
FOREIGN KEY(paintings_id) references pantings(painting_id)
);
I cut and pasted your create table statement as-is...and it worked fine. Your error must be generated from something other than mysql....which brings me to another point...what's the error?
....nevermind...I see your error in the subject field.....not sure...as I said it worked fine on MySQL version 5.1.
Make sure that your foreign key reference columns have the same definition as the columns in your other tables.
For example, you are adding a foreign key with this column as the reference:
customer_id INT UNIQUE NOT NULL
Which means 'customers_id' in your 'customers' table must be:
customers_id INT NOT NULL (possibly AUTO_INCREMENT)
If you define one as 'UNSIGNED' and/or 'NULL' / 'NOT NULL', the referenced column must also have those attributes. See Using Foreign Key Constraints.

C# How can I clear all foreign key references in order to save the deletion of the primary key record to the database?

When I perform a delete on a primary key record it deletes the foreign key record and saves the change, but when it goes to delete the primary key record it won't let me save the deletion of the primary key record to the database. Instead it gives the following error:
Error: The primary key value cannot be deleted because references to this key still exist. [ >Foreign key constraint name = FK_PERSONID ]
According to what I've seen online I should be able to disable the EnforceConstraints either through code or through the DataSet Designer View. After doing it through code failed I tried changing the EnforceConstraints to False in the DataSet Designer View. It still gives the same error. I tried editing the foreign key constraint to do a Cascade Delete and it still gives the same error.
Trying to do it with only the Cascade Delete without the code got the same error.
This is the portion where I perform the deletes.
bizDocStartupDBDataSet1.EnforceConstraints = false;
BizDocStartupDBDataSet1.EmployeeTitlesRow oldEmployeeTitlesRow;
oldEmployeeTitlesRow = bizDocStartupDBDataSet1.EmployeeTitles.FindByPERSONIDCOMPANYID(currentPersonID,1);
oldEmployeeTitlesRow.Delete();
this.employeeTitlesTableAdapter.Update(this.bizDocStartupDBDataSet1.EmployeeTitles);
this.Validate();
this.employeeTitlesBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.bizDocStartupDBDataSet1);
this.peopleProfilesBindingSource.RemoveCurrent();
SaveData();
bindingNavigatorDeleteItem.Enabled = true;
bizDocStartupDBDataSet1.EnforceConstraints = true;
The SaveData function is just the standard save with a refilling of the table, but the change to the datatable can't be saved to the database because there are still references to the Foreign Key.
How do I clear out all the references to the foreign key after the key with the foreign record has been deleted so I can save the deletion of the primary key record to the database?
Foreign keys are used to prevent records from getting orphaned, so getting rid of the foreign key is only a solution when you didn't need it in the first place. Having said that, you'll have to cascade your deletes and you start with the record in the table that contains the foreign key, delete that FIRST, then delete the record with the primary key. You may have to make two dataadapters the way you're doing it, but ideally you'd do this all with a stored proc.
If you have binded tables be sure you are not delete records from the primary table unless you don't use them anymore.
if there is another table that contains a foreing key of the record you are trying to delete it you will have that problem.
Delete those record that are foreign keys of that record you want to delete and then at last delete that record you actually want to delete.
So i guess you should be careful of what you are trying to delete. Hope it helps!
And for the last question: you will have to delete all the records that are foreign.
EnforceConstraints is a property of a C# DataSet object. Modifying this value will not affect the structure or behaviors of your database.
Cascading delete is one way to solve your problem -- triggers are another. But as a general rule I don't believe you should rely on automated deletes in the database. I think it is better to use a stored procedure to manage this delete by finding all dependencies and remove them first, and then going ahead with the delete from the primary key table. This way, you know exactly what's going on in your database.
I'm surprised that you continued to get a FK error after modifying the FK with cascading delete. Maybe post the exact error and your updates to the table and we can have a better grip on what's happening?

How to update primary key value in entity framework?

I have table(and also entity in Entity Data Model) Person with following fields:
Name Type
SocialID String
FirstName String
LastName String
which SocialID is Primary Key. I want to update value of SocialID for each record. However when i try to update this field in Entity Framework I get following error:
The property 'SocialID' is part of the object's key information and cannot
be modified.
The code that i get above error is:
foreach (var p in Entity.Persons)
{
p.SocialID= p.SocialID + "00";
Entity.SaveChanges();
}
How I can do this??
As mentioned by the others, you can't do it in code. You will have to make your update in SQL. Either in a migration or directly in SQL Server Management Studio (or the equivalent if you're using a different database).
UPDATE Person -- Or 'Persons' if that's what your table is called
SET SocialID = SocialID + '00'
It will require a lot more work than this if you have other tables use this column as a foreign key (you'll have to drop the constraints first -- on all tables that reference your primary key -- then fix the data and recreate the constraints). Or as Moe said in the comments, you can set your foreign keys to cascade on update.
As per my knowledge primary key once generated cant be updated programatically,that defies the purpose of primary key.
It'll be better if you insert all your data again with new primary keys and delete old data.
Why would you want to change the primary key? Entity framework will be using that field to identify the object, you can't change its value while it is the primary key.
Based on the first answer I suggest you change the table Person to have its own primary key, let's say PersonID and mantain the SocialID as a foreign key to the Social table. If you need a person to have several Social records you may need to create other table to correspond the PersonId to several SocialId, removing the SocialId from the person table.

When deleting a record that is referenced in another table, how do I know when to stop?

I have the following table structure in my database:
create table Encargado(
ID int primary key,
Nombre varchar(300),
)
create table Area(
ID int primary key,
Nombre varchar(300),
Jefe int foreign key references Encargado(ID)
)
create table Carrera(
ID int primary key,
Nombre varchar(300),
Area int foreign key references Area(ID)
)
create table Formacion(
ID int primary key,
Grado varchar(300),
Lugar varchar(300)
)
create table Docente(
ID int primary key,
Nombre varchar(300),
Carrera int foreign key references Carrera(ID),
Formacion int foreign key references Formacion(ID),
Horario varchar(300)
)
create table Evaluacion(
ID int primary key,
Docente int foreign key references Docente(ID),
Evaluador varchar(300),
Secuencia int,
Pizarra int,
Audiovisual int,
Letra int,
Voz int,
GestosVocabulario int,
Ejemplificacion int,
Respuestas int,
DominioEscenico int,
Participacion int,
Observacion varchar(4000),
Materias varchar(3000),
Valido bit
)
create table Seguimiento(
ID int primary key,
Docente int foreign key references Docente(ID),
Modulo int,
Semestre int,
Ano int,
Fecha datetime,
Hora datetime,
OrdenSecuencia bit,
OrdenSecuenciaObservacion varchar(200),
PortafolioAlumno bit,
PortalofioAlumnoObservacion varchar(200),
AspectosParaEntrevista varchar(3000),
Conclusiones varchar(3000),
Evaluador varchar(300),
DirectorDeArea int foreign key references Encargado(ID),
EncargadoControl int foreign key references Encargado(ID),
)
Say I want to delete an Area, how would I do this? I would need to also delete all Carreras and also all the Docentes.
public void Delete(Area area)
{
db.Carreras.DeleteAllOnSubmit(area.Carreras);
//I'm stuck here. Is this what I should be doing?
}
Can someone suggest how to handle this?
I'm using C# and Linq-to-SQL. I feel I may have dug myself into a hole by using this table structure or perhaps that's one of the downfalls of a relational database? :\
I wouldn't handle this on the Linq-to-SQL side, I'd use cascading deletes on the database side if you truly want to delete all the child records.
For example, with Oracle you can add a "ON DELETE CASCADE" clause to your create table statements, refer to this link.
The cascading delete will handle deleting all the records from the child tables, all with a single delete operation. The beauty of this approach is that no matter where you perform the operation, albeit via Linq-To-SQL, JAVA, ROR, PHP, etc, the logic is centralized in the DB so it works the same way no matter who does the delete.
It should depend on how you want to handle your foreign key relationship. i.e. deleting foreign references or leaving them in case they have other entries dependent on them, etc.
See referential integrity http://msdn.microsoft.com/en-us/library/ms186973.aspx
So, in the end you should probably let the DB handle it.
Say I want to delete an Area, how
would I do this? I would need to also
delete all Carreras and also all the
Docentes.
On the face of it, it seems you want to change the declarative referential integrity (DRI) action for ON DELETE from the default NO ACTION (i.e. prevent the referenced row from being deleted) to CASCADE (i.e. also delete the rows in the referening table).
Note that such logic usually suggests that the referening column (e.g. Carrera.Area) should be defined as NOT NULL.
For example:
CREATE TABLE Carrera
(
...
Area INTEGER NOT NULL
REFERENCES Area (ID)
ON DELETE CASCADE
);
CREATE TABLE Docente
(
...
Carrera INTEGER NOT NULL
REFERENCES Carrera (ID)
ON DELETE CASCADE,
...
);
However, looking deeper we see that
Evaluacion REFERENCES Docente
Seguimiento REFERENCES Docente
You need to consider whether these too require the ON DELETE CASCADE DRI action.
Furthermore:
Seguimiento REFERENCES Encargado -- twice
Area REFERENCES Encargado
In other words, you have a potential cycle here. Even if your DBMS would allow ON DELETE CASCADE DRI actions on all these (SQL Server, for example, would not) you should consider managing the logic by 'manually' removing rows.
Something else to consider, seeing all those seemingly NULLable columns (but how can you primary key columns be nullable...?) you could consider the ON DELETE SET NULL DRI action. Personally, I would clarify the design by removing the NULLable columns are creating new relationship tables but that could involve a lot of work :)
Have you considered a "logical delete" instead of a physical delete?
Logical deletes make sense when you want to keep historical access to data (for reports or queries) even after they have become obsolete.
Example: your school used to teach Latin, and have a number of professors teaching it, and a number of students enrolled.
Next year, Latin gets removed from the available courses. One of the professors retires, the others go on with other courses. Students still need to prove they got a vote in Latin, even if this will not be part of future offerings.
Solution: add a boolean flag to the Course table (Active=Y/N) and adapt your program so that it excludes Courses (or professors, or anything else) having "Active=N" from queries that must return what is "live", and keep them in for historical reports.

Categories