2
votes

Comment puis-je insérer dans SQL et ignorer ce qui existe déjà?

J'essaie de dupliquer des enregistrements dans une table et les nouveaux enregistrements ont un nouvel CompanyID, tout le reste est identique. Certains enregistrements existent déjà et empêchent l'exécution de mon script. Comment puis-je ignorer les enregistrements qui existent déjà?

SELECT * INTO #TempTable FROM UserRole WHERE 
CompanyID = @oldComp;
ALTER TABLE #TempTable DROP COLUMN id;
UPDATE #TempTable SET CompanyID = @newComp;
INSERT INTO UserRole SELECT * FROM #TempTable;
DROP TABLE #TempTable;


6 commentaires

Left Join avec où jointableid est nul .


Votre code n'a pas de sens pour moi. Vous insérez N colonnes dans la table temporaire à partir de UserRole . Mais, à la fin, vous insérez N-1 colonnes dans UserRole à partir de la table temporaire.


Utilisez SELECT * FROM #TempTable WHERE NOT EXISTS (...) pour exclure les lignes existantes de la requête


Y a-t-il de nombreuses colonnes? En spécifiant les colonnes explicitement, vous pouvez le faire dans une seule instruction sans table temporaire.


COLUMN id dans la table UserRole est-il configuré pour utiliser AUTO INCREMENT également connu sous le nom IDENTITY (en supposant qu'il s'agit d'un INT) ?


@PeterB ouais c'est pourquoi j'ai la goutte là-dedans.


3 Réponses :


4
votes

Pourquoi ne pas simplement utiliser l'instruction UPDATE :

INSERT INTO UserRole (col1, col2, . . .) 
     SELECT t.col1, t.col2, . . . 
     FROM #TempTable t
     WHERE NOT EXISTS (SELECT 1 FROM UserRole U WHERE u.col = t.col);

EDIT: Si vous souhaitez insérer de nouveaux enregistrements, utilisez NON EXISTANT :

UPDATE UserRole 
     SET CompanyID = @newComp
WHERE CompanyID = @oldComp;


0 commentaires

1
votes

Essayez ceci:

SELECT * FROM #TempTable
EXCEPT 
SELECT * FROM UserRole

L'instruction EXCEPT ci-dessous:

SELECT * 
INTO #TempTable 
FROM UserRole 
WHERE CompanyID = @oldComp;

ALTER TABLE #TempTable DROP COLUMN id;

UPDATE #TempTable SET CompanyID = @newComp;

INSERT INTO UserRole 
SELECT * FROM #TempTable
EXCEPT 
SELECT * FROM UserRole

DROP TABLE #TempTable;

vous donnera tous les enregistrements de le #TempTable qui n'existe pas dans la table cible.


2 commentaires

Cela pourrait être une bonne approche, s'il n'y a pas de champ de clé de substitution / d'incrémentation automatique, car si tel est le cas, les lignes de #temptable ne correspondent pas aux lignes existantes UserRole.


@GolezTrol Oui, vous avez raison. Mais s'il existe une telle clé, vous n'êtes pas autorisé à renseigner sa valeur, elle peut donc simplement être exclue de SELECT .



2
votes

Je ne sais pas ce que sont tous les noms de colonnes, mais si vous voulez / êtes capable de les lister, alors peut-être qu'un simple INSERT INTO ... SELECT ferait ici:

INSERT INTO UserRole (CompanyID, col1, col2, col3)
SELECT @newComp, u1.col1, u1.col2, u1.col3
FROM UserRole u1
WHERE
    CompanyID = @oldComp AND
    NOT EXISTS (SELECT 1 FROM UserRole u2
                WHERE u1.col1 = u2.col1 AND u1.col2 = u2.col2 AND u1.col3 = u2.col3 AND
                      u2.CompanyID = @newComp);

Si le nouvel identifiant d'entreprise peut déjà apparaître dans certains enregistrements et que vous souhaitez éviter d'insérer de nouveaux enregistrements pouvant avoir la même valeur dans toutes les autres colonnes, ajoutez un code EXISTS > clause à la requête ci-dessus:

INSERT INTO UserRole (CompanyID, col1, col2, col3)
SELECT @newComp, col1, col2, col3
FROM UserRole
WHERE CompanyID = @oldComp;


2 commentaires

Et puis toujours utiliser là où n'existe pas pour exclure les lignes existantes, ce qui était la raison réelle de la question.


@GolezTrol J'ai ajouté une mise à jour pour couvrir cette possibilité, mais je ne suis pas sûr que cela existe pour l'OP. Il me semble que l'OP veut juste générer de nouveaux enregistrements qui n'existent pas déjà logiquement.