C'est la requête que j'utilise:
DELETE TB1.*, TB2.*
FROM TB1
INNER JOIN TB2 ON TB1.PersonID = TB2.PersonID
WHERE (TB1.PersonID)='2'
Cela fonctionne très bien dans MS Access mais génère une erreur (syntaxe incorrecte près de ','.) Dans SQL Server Express 2005.
Comment le résoudre? S'il vous plaît aider.
Vous ne pouvez pas utiliser DELETE
à partir de plusieurs tables avec une seule expression dans SQL 2005
- ou de tout autre code SQL standard à cet égard. Access
est l'exception ici.
La meilleure méthode pour obtenir cet effet consiste à spécifier FOREIGN KEYS
entre les tables avec un ON
DELETE
trigger
.
Pourquoi n'utilisez-vous pas un DELETE CASCADE FK
?
Cela ne peut pas être fait en une seule déclaration. Vous devrez utiliser 2 déclarations
DELETE FROM TB1 WHERE PersonID = '2';
DELETE FROM TB2 WHERE PersonID = '2';
Comme je le sais, vous ne pouvez pas le faire en une phrase.
Mais vous pouvez créer une procédure stockée qui supprime les modifications souhaitées dans n'importe quelle table d'une transaction, ce qui est presque identique.
Spécifiez la clé étrangère pour les tables de détails faisant référence à la clé primaire du maître et définissez la règle de suppression = Cascade.
Désormais, lorsque vous supprimez un enregistrement de la table principale, tous les autres enregistrements de la table de détails basés sur la valeur de la clé primaire de suppression de lignes sont automatiquement supprimés.
Ainsi, dans ce cas, une requête de suppression unique de la table principale peut supprimer des données de tables principales ainsi que des données de tables enfants.
Je ne pense pas que vous puissiez supprimer plusieurs tables à la fois (même si je ne suis pas certain).
Il me semble cependant que vous feriez mieux de réaliser cet effet avec une relation qui supprime les cascades. Si vous faites cela, vous pourrez supprimer l'enregistrement d'une table et les enregistrements de l'autre seront automatiquement supprimés.
Par exemple, supposons que les deux tables représentent un client et ses commandes. Si vous configurez la relation avec les suppressions en cascade, vous pouvez simplement supprimer un enregistrement dans la table des clients et les commandes seront automatiquement supprimées.
Voir la documentation MSDN sur en cascade des contraintes d'intégrité référentielle .
Vous pouvez utiliser quelque chose comme ce qui suit:
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name IN ("TB2","TB1") -- use these databases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
DELETE FROM @name WHERE PersonID ='2'
FETCH NEXT FROM db_cursor INTO @name
END
J'utilise ceci pour nettoyer des données dans des bases de données de test/développement. Vous pouvez filtrer par nom de table et nombre d'enregistrements.
DECLARE @sqlCommand VARCHAR(3000);
DECLARE @tableList TABLE(Value NVARCHAR(128));
DECLARE @TableName VARCHAR(128);
DECLARE @RecordCount INT;
-- get a cursor with a list of table names and their record counts
DECLARE MyCursor CURSOR FAST_FORWARD
FOR SELECT t.name TableName,
i.rows Records
FROM sysobjects t,
sysindexes i
WHERE
t.xtype = 'U' -- only User tables
AND i.id = t.id
AND i.indid IN(0, 1) -- 0=Heap, 1=Clustered Index
AND i.rows < 10 -- Filter by number of records in the table
AND t.name LIKE 'Test_%'; -- Filter tables by name. You could also provide a list:
-- AND t.name IN ('MyTable1', 'MyTable2', 'MyTable3');
-- or a list of tables to exclude:
-- AND t.name NOT IN ('MySpecialTable', ... );
OPEN MyCursor;
FETCH NEXT FROM MyCursor INTO @TableName, @RecordCount;
-- for each table name in the cursor, delete all records from that table:
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sqlCommand = 'DELETE FROM ' + @TableName;
EXEC (@sqlCommand);
FETCH NEXT FROM MyCursor INTO @TableName, @RecordCount;
END;
CLOSE MyCursor;
DEALLOCATE MyCursor;
Informations de référence:
vous pouvez rejoindre comme ça
DELETE t2
FROM TB1 t1
INNER JOIN TB2 t2 ON t1.PersonID = t2.PersonID
WHERE t1.PersonID = '2'
mais comme Alex l'a mentionné, un seul à la fois.
Vous avez besoin d'une contrainte de cascade sur la table pour tout faire en même temps
CREATE PROCEDURE sp_deleteUserDetails
@Email varchar(255)
AS
declare @tempRegId as int
Delete UserRegistration where Email=@Email
set @tempRegId = (select Id from UserRegistration where Email = @Email)
Delete UserProfile where RegID=@tempRegId
RETURN 0