Je n'ai jamais utilisé de transaction, de commit et de restauration avant et je dois maintenant utiliser un. J'ai vérifié en ligne, etc. pour des exemples pour vous assurer que je l'utilise correctement, mais je ne sais toujours pas si j'ai codé ce correct. J'espère que quelqu'un peut revoir et me conseiller si cela semble correct.
Fondamentalement, j'ai 2 bases de données pour une application. L'une est une archive - une signification de données qui ne sera plus manipulée par les utilisateurs seront déplacées vers cette DB. Mais dans le cas où ils en ont déjà besoin, je déplacerai les données nécessaires à la base de données principale à utiliser. Mon procédé stocké est ci-dessous:
CREATE PROCEDURE [dbo].[spReopenClosed]
(
@Return_Message VARCHAR(1024) = '' OUT,
@IID uniqueidentifier,
@OpenDate smalldatetime,
@ReopenedBy uniqueidentifier
)
AS
BEGIN
SET NOCOUNT ON;
/******************************
* Variable Declarations
*******************************/
DECLARE @ErrorCode int
/******************************
* Initialize Variables
*******************************/
SELECT @ErrorCode = @@ERROR
IF @ErrorCode = 0
BEGIN TRANSACTION
/****************************************************************************
* Step 1
* Copy the Closed from the Archive
****************************************************************************/
INSERT INTO OPS.dbo.SM_T_In
SELECT
FROM OPS_ARCHIVE.Archive.SM_T_In W
WHERE W.GUID = @IID
AND W.OpenDate = @OpenDate
IF @ErrorCode <> 0
BEGIN
-- Rollback the Transaction
ROLLBACK
RAISERROR ('Error in Copying from the archive', 16, 1)
RETURN
END
/****************************************************************************
* Step 2
* copy the notes
****************************************************************************/
INSERT INTO OPS.dbo.SM_T_Notes
SELECT
FROM OPS_ARCHIVE.Archive.SM_T_Notes W
WHERE W.GUID = @IID
IF @ErrorCode <> 0
BEGIN
-- Rollback the Transaction
ROLLBACK
RAISERROR ('Error in copying the notes', 16, 1)
RETURN
END
/****************************************************************************
* Step 3
* Delete the from the Archive - this will also delete the notes
****************************************************************************/
DELETE
FROM OPS_ARCHIVE.Archive.SM_T_In
WHERE OPS_ARCHIVE.Archive.SM_T_In.GUID = @IID
IF @ErrorCode <> 0
BEGIN
-- Rollback the Transaction
ROLLBACK
RAISERROR ('Error in deleting the items from the Archive', 16, 1)
RETURN
END
COMMIT
BEGIN
SELECT @ErrorCode = @@ERROR
IF @ErrorCode = 0
SELECT @Return_Message = 'All data was moved over'
END
/*************************************
* Get the Error Message for @@Error
*************************************/
IF @ErrorCode <> 0
BEGIN
SELECT @Return_Message = [Description] -- Return the SQL Server error
FROM master.dbo.SYSMESSAGES
WHERE error = @ErrorCode
END
/*************************************
* Return from the Stored Procedure
*************************************/
RETURN @ErrorCode -- =0 if success, <>0 if failure
END
J'ai deux inserts qui déplacent les données de 2 tables de la base de données d'archives. Si ces insertions réussissent, je supprimerai les données de l'archive DB. J'apprécierais des commentaires à ce sujet, je dois m'assurer que je le fais bien.
Merci
Premièrement, les bases de données sont assez fiables. Et s'ils échouent, vous avez un gros problème que de gérer des transactions individuelles. Donc, mes commentaires seraient que vous avez trop d'erreur vérifier une transaction simple. Un insert défaillant est un événement aussi inhabituel que vous n'écririez normalement pas de code pour le gérer.
Deuxièmement, ce code ne "attrapera" pas d'erreurs:
IF @ErrorCode <> 0
Une erreur dans l'instruction SQL abandonnera la procédure stockée et revenir au client. Vous auriez à ... essayer ... Catch Pour gérer une erreur dans une procédure stockée.
Troisièmement, j'essaie d'éviter raiserr
. Il peut faire des choses inattendues sur le serveur et le côté du client. Au lieu de cela, envisagez d'utiliser un paramètre output
pour renvoyer des informations d'erreur au programme client.