J'écris une requête de base SELECT
, quelque chose comme:
SELECT id, pname, pnumber
FROM tableName
WHERE pnumber IS NOT NULL
Je voudrais ensuite effectuer un INSERT
en utilisant le résultat de ce SELECT
comme ceci:
IF {**the above SELECT query returned 0 rows**}
BEGIN
INSERT INTO tableName (pname,pnumber) VALUES ('bob', '38499483')
END
Ma question est, comment puis-je vérifier le **the above SELECT query returned 0 rows**
?
IF NOT EXISTS (SELECT ...)
BEGIN
INSERT ...
END
Vous pouvez également le faire, si vous vous attendez à ce que la requête retourne souvent des lignes (en particulier beaucoup de lignes), ce qui peut offrir une meilleure opportunité de court-circuiter:
IF EXISTS (SELECT ...)
BEGIN
PRINT 'Do nothing.';
END
ELSE
BEGIN
INSERT ...
END
...puisque IF EXISTS
reviendra immédiatement après avoir atteint la toute première ligne correspondante.
Je ne recommande pas d'utiliser @@ROWCOUNT
uniquement parce que vous devrez à chaque fois matérialiser (et ignorer) l'ensemble des résultats.
Dans MySQL pour vérifier non. des lignes retournées par la dernière requête de sélection
select FOUND_ROWS();
vous pouvez utiliser @@ROWCOUNT
SELECT id, pname, pnumber
FROM tableName
WHERE pnumber IS NOT NULL
après cette sélection, demandez @@ROWCOUNT
IF @@ROWCOUNT = 0
BEGIN
INSERT ...
END
De cette façon, vous pouvez renvoyer certaines données et vérifier si cela a donné des résultats ou non
J'ai vu des gens avoir des problèmes de conception avec cette logique.
1 - Tester l'existence de l'enregistrement.
2 - S'il n'existe pas, insérez l'enregistrement.
Surtout si la concurrence entre en jeu. Selon le niveau d'isolement, vous pouvez avoir des données en double ou des violations de clé.
Pourquoi ne pas placer une clé primaire sur pname et pnumber en premier lieu. Je suppose que vous parlez d'une table de personnes.
Mon exemple.
--
-- Setup sample table w/data
--
-- Sample table
create table #person
(
person_id int identity (1, 1),
person_name varchar(64) not null,
person_no varchar(16) not null
);
go
-- primary key
alter table #person
add primary key (person_no, person_name)
go
-- first insert works
insert into #person (person_name, person_no) values ('bilbo', 123)
go
La clé de la solution consiste à intercepter la violation de clé primaire. Ignorer cette erreur peut être bon ou mauvais selon votre logique métier.
Je décide d'ignorer le problème.
--
-- Ignore primary key violations
--
-- Try these steps
BEGIN TRY
-- Second insert fails
insert into #person (person_name, person_no) values ('bilbo', 123)
END TRY
-- Error Handler
BEGIN CATCH
-- Ignore PK error
IF ERROR_NUMBER() <> 2627
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
END CATCH
Cette solution élimine les entrées en double et ne signale pas les violations de PK.