2009-12-30 5 views
0

J'utilise le sql ci-dessous pour importer des données d'un fichier de l'intranet. Cependant, de temps en temps, il y aura une erreur de timeout et le processus échouera, c'est pourquoi j'utilise une transaction. Si la transaction échoue, je veux que ImportedTable soit effacé. Cependant, cela ne semble pas arriver. Y a-t-il quelque chose qui me manque ici?Timeout dans SQL Procédure

ALTER PROCEDURE [dbo].[pr_ImportData] 
@StoreCode varchar(10), 
@UserId varchar(100) 
AS 

BEGIN TRANSACTION 

-- 1) Clear the data 
exec pr_INTRANET_ClearData @StoreCode, @UserId 

IF @@ERROR <> 0 
BEGIN 
ROLLBACK TRANSACTION 
GOTO EXIT1 
END 

-- 2) Add the new data to the history Table 
INSERT INTO data_History (...) 
SELECT ... from ImportedTable WHERE StoreCode = @StoreCode and UserId = @UserId 

IF @@ERROR <> 0 
BEGIN 
ROLLBACK TRANSACTION 
GOTO EXIT1 
END 

-- 3) Add the data to the live table 
INSERT INTO data_Live (...) 
SELECT ... from ImportedTable WHERE StoreCode = @StoreCode and UserId = @UserId 

IF @@ERROR <> 0 
BEGIN 
ROLLBACK TRANSACTION 
GOTO EXIT1 
END 

IF @@ERROR <> 0 
BEGIN 
ROLLBACK TRANSACTION 
GOTO EXIT1 
END 

EXIT1: 
-- 4) Delete the rows from the temp table 
DELETE FROM ImportedTable WHERE StoreCode = @StoreCode and UserId = @UserId 

COMMIT TRANSACTION 

Mise à jour 1: Je suis en cours d'exécution contre ce SQL 2000 et SQL2005.

Mise à jour 2: Pour clarifier: ImportedTable n'est jamais effacé à Exit1.

+0

Est-ce que pr_INTRANET_ClearData renvoie un code d'erreur? Je ne pense pas que l'erreur @@ fonctionnera avec un appel comme celui-ci. Essayez de déclarer un @Error, puis de définir exec @Error = pr_INTRANET_ClearData @StoreCode, @UserId. Assurez-vous que le pr_INTRANET_ClearData renvoie l'erreur @@ ou un code d'erreur personnalisé de la procédure. Il pourrait raccrocher à partir de ce que cette procédure fait. –

Répondre

6

SET XACT_ABORT ON va faire toute erreur pour annuler la transaction, supprimant le besoin d'annuler explicitement en cas d'erreur. Vous devriez également envisager d'utiliser BEGIN TRY/BEGIN CATCH, ce qui est nettement plus facile à programmer que de vérifier @@ ERROR après chaque instruction.

+0

Cela fonctionnerait-il dans SQL2000 et SQL2005? – vikasde

+0

SET XACT_ABORT fonctionnera dans les deux. Try/Catch est seulement pour SQL2005 et plus. – MartW

+0

Astuce génial. Merci! – vikasde