IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

[2008 R2] Arithmetic overflow


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut [2008 R2] Arithmetic overflow
    Bonjour,

    Je rencontre un souci lors de l'exécution d'un job et je ne parviens pas à situer le problème.

    Voici le code du step qui pose problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    /*----------------------------------------------------------------------------------*
    *SCRIPT D'IMPORTATION DE L'ANCIENNE DB GIFTCARD DANS LA NOUVELLE DB                    *
    *  _                                                                          _        *
    * /!\ PENSER A DESACTIVER LES TRIGGER AFTER UPDATE SUR LES TABLES STS ET SFS /!\    *    
    * ¯¯¯                                                                         ¯¯¯    *
    *-----------------------------------------------------------------------------------*/
    SET ANSI_WARNINGS OFF;
     
    DECLARE @SEQNRHIST    INT;
    DECLARE @BARCODE    VARCHAR(13);
    DECLARE @DATE        DATETIME;
    DECLARE @ACTION        VARCHAR(1);
    DECLARE    @ORIGIN        INT;
    DECLARE @DESTTYPE    INT;
    DECLARE    @DEST        INT;
    DECLARE @VALUE        INT;
    DECLARE    @SALETYPE    INT;
    DECLARE    @USERTYPE    INT;    
     
    DECLARE @GFT_ID        INT;
    DECLARE @STR_ID        INT;
    DECLARE @DOS_ID        INT;
    DECLARE @DECIMAL_VALUE    DECIMAL(6,2);
    DECLARE @TMP        VARCHAR(100);
    DECLARE @TRN_TILL    SMALLINT;
    DECLARE @TRN_TICKET    SMALLINT;
    DECLARE @USERNAME    VARCHAR(50);
     
    DECLARE C CURSOR FOR
     
    SELECT
            SEQNRHIST,
            BARCODE,
            DATTIM,
            ACTION,
            ORIGIN,
            DESTTYPE,
            DEST,
            VALUE,
            SALETYPE,
            USERTYPE
    FROM
            DBO.T_CHEQUE_ACHAT_HISTORY
    WHERE
            ACTION = 'T'
    ORDER BY
            DATTIM,
            SEQNRHIST
     
    OPEN C;
     
    FETCH NEXT FROM C INTO @SEQNRHIST, @BARCODE, @DATE, @ACTION, @ORIGIN, @DESTTYPE, @DEST, @VALUE, @SALETYPE, @USERTYPE;
     
    WHILE @@FETCH_STATUS = 0
    BEGIN
        --ON RECUPERE L'ID DU GIFT
        EXEC TMP_UP_CREATE_GIFT_IF_NOT_EXISTS @BARCODE, @GFT_ID OUTPUT, @VALUE;
     
        --ON NOTE LA LIGNE EN COURS DE TRAITEMENT POUR IDENTIFIER SI PLANTAGE
        UPDATE DBO.T_CURRENT_LINE_PROCESSING_CLP
        SET
                SEQNRHIST = @SEQNRHIST,
                BARCODE = @BARCODE,
                ACTION = @ACTION
     
        --ON DEFINIT SI L'UTILISATEUR EST NORMAL OU ADMIN
        IF @USERTYPE <> 0
            SET @USERNAME = 'ADMIN';
        ELSE
            SET @USERNAME = 'NORMAL';
     
        --VENDU A LA CAISSE (TTR_ID = 0)
        IF @ACTION = 'T'
        BEGIN
            --ON RECUPERE L'ID DU MAGASIN
            SET @ORIGIN = @ORIGIN * 10000
            IF @ORIGIN = 0
                SET @STR_ID = 17
            ELSE
                EXEC TMP_UP_GET_STORE_ID @ORIGIN, @STR_ID OUTPUT;
     
            --ON RECUPERE LA CAISSE ET LE TICKET
            SET @TMP =  RIGHT('000000'+CAST(@DEST AS VARCHAR(6)),6);
            SET @TRN_TILL = CAST(LEFT(@TMP,2) AS SMALLINT);
            SET @TRN_TICKET = CAST(RIGHT(@TMP,4) AS SMALLINT);
            IF @USERTYPE <> 0 --SI L'UTILISATION EST SIMULEE PAR UN ADMIN --> CAISSE ET TICKET = 0
            BEGIN
                SET @TRN_TICKET = 0;
                SET @TRN_TILL = 0;
            END
     
            --ON INSERE LA TRANSACTION
            SET @DECIMAL_VALUE = CAST(@VALUE AS DECIMAL(10,2)) / 100;
            INSERT INTO DBO.T_TRANSACTION_TRN(    TTR_ID, GFT_ID, STR_ID, TRN_DATE, TRN_TILL, TRN_TICKET, TRN_VALUE, TRN_CREATED_BY)
            VALUES(0, @GFT_ID, @STR_ID, @DATE, @TRN_TILL, @TRN_TICKET, @DECIMAL_VALUE, @USERNAME);
     
            --ON LE RETIRE DU STOCK DU MAGASIN
            UPDATE dbo.V_STORE_STOCK_VSS
            SET
                    SSS_DATE_OUT = @DATE
            WHERE
                    GFT_ID = @GFT_ID
                AND SSS_DATE_OUT IS NULL
                AND STR_ID = @STR_ID
        END
     
     
        FETCH NEXT FROM C INTO @SEQNRHIST, @BARCODE, @DATE, @ACTION, @ORIGIN, @DESTTYPE, @DEST, @VALUE, @SALETYPE, @USERTYPE;
    END
     
    CLOSE C;
    DEALLOCATE C;
    Le message d'erreur étant celui-ci :
    Executed as user: XXXXXXXX. Arithmetic overflow occurred. [SQLSTATE 01000] (Message 3606) Cannot insert the value NULL into column 'CHQ_AMOUNT', table 'GIFT_MANAGEMENT.dbo.T_CHEQUE_CHQ'; column does not allow nulls. INSERT fails. [SQLSTATE 23000] (Error 515) The statement has been terminated. [SQLSTATE 01000] (Error 3621). The step failed.
    J'ai donc été voir dans le seul endroit du code où une insertion dans la table T_CHEQUE_CHQ est susceptible d'avoir lieu. Il s'agit de la procédure stockée TMP_UP_CREATE_GIFT_IF_NOT_EXISTS dont voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    USE [GIFT_MANAGEMENT]
    GO
     
    /****** Object:  StoredProcedure [dbo].[TMP_UP_CREATE_GIFT_IF_NOT_EXISTS]    Script Date: 01/18/2013 10:28:14 ******/
    SET ANSI_NULLS ON
    GO
     
    SET QUOTED_IDENTIFIER ON
    GO
     
     
    CREATE PROCEDURE [dbo].[TMP_UP_CREATE_GIFT_IF_NOT_EXISTS]
        @BARCODE    CHAR(13),
        @GFT_ID        INT OUTPUT,
        @VALUE        INT = NULL
    AS
    BEGIN
        SET NOCOUNT ON;
        SET ANSI_WARNINGS OFF;
     
        DECLARE @TCA_ID        SMALLINT = 0;
        DECLARE @TCA_CODE    SMALLINT = CAST(SUBSTRING(@BARCODE,3,3) AS SMALLINT);
        DECLARE @CRD_SERIAL    INT    = CAST(SUBSTRING(@BARCODE,6,7) AS INT);
     
        DECLARE @CHQ_TYPE    TINYINT = CAST(SUBSTRING(@BARCODE,3,2) AS TINYINT);
        DECLARE @CHQ_YEAR    TINYINT = CAST(SUBSTRING(@BARCODE,5,1) AS TINYINT);
        DECLARE @CHQ_SERIAL INT = CAST(SUBSTRING(@BARCODE,6,7) AS INT);
     
        IF LEFT(@BARCODE,2) = '21' --CHEQUE
        BEGIN
            --CREATION DU CHEQUE S'IL N'EXISTE PAS
            IF NOT EXISTS    (
                            SELECT
                                    *
                            FROM
                                    DBO.T_CHEQUE_CHQ
                            WHERE
                                    CHQ_PREFIX = 21
                                AND    CHQ_TYPE = @CHQ_TYPE
                                AND    CHQ_YEAR = @CHQ_YEAR
                                AND    CHQ_SERIAL = @CHQ_SERIAL
                            )
            BEGIN
                INSERT INTO    DBO.T_GIFT_GFT DEFAULT VALUES;
                SET @GFT_ID = SCOPE_IDENTITY();
     
                INSERT INTO    DBO.T_CHEQUE_CHQ(GFT_ID, CHQ_PREFIX, CHQ_TYPE, CHQ_YEAR, CHQ_SERIAL, CHQ_AMOUNT)
                VALUES(@GFT_ID, 21, @CHQ_TYPE, @CHQ_YEAR, @CHQ_SERIAL, CAST(@CHQ_TYPE AS DECIMAL(6,2)));
            END
            ELSE
                SELECT
                        @GFT_ID = GFT_ID
                FROM
                        DBO.T_CHEQUE_CHQ
                WHERE
                        CHQ_TYPE = @CHQ_TYPE
                    AND    CHQ_YEAR = @CHQ_YEAR
                    AND    CHQ_SERIAL = @CHQ_SERIAL
        END
        ELSE
            IF LEFT(@BARCODE,2) = '24' --CARTE
            BEGIN
                --CREATION DU TYPE DE CARTE S'IL N'EXISTE PAS
                IF NOT EXISTS    (
                                SELECT
                                        *
                                FROM
                                        DBO.T_TYPE_CARD_TCA
                                WHERE
                                        TCA_CODE = @TCA_CODE
                                )
                BEGIN
                    INSERT INTO    DBO.T_TYPE_CARD_TCA(TCA_STANDARD, TCA_CODE)
                    VALUES(0, @TCA_CODE);
                    SET @TCA_ID = SCOPE_IDENTITY();
                END
                ELSE
                    SELECT    
                            @TCA_ID = TCA_ID
                    FROM
                            DBO.T_TYPE_CARD_TCA
                    WHERE
                            TCA_CODE = @TCA_CODE
     
                --CREATION DE LA CARTE SI ELLE N'EXISTE PAS
                IF NOT EXISTS    (
                                SELECT
                                        *
                                FROM
                                        DBO.T_CARD_CRD
                                WHERE
                                        TCA_ID = @TCA_ID
                                    AND    CRD_SERIAL = @CRD_SERIAL
                                )
                BEGIN
                    INSERT INTO DBO.T_GIFT_GFT DEFAULT VALUES;
                    SET @GFT_ID = SCOPE_IDENTITY();
     
                    INSERT INTO DBO.T_CARD_CRD(GFT_ID, CRD_PREFIX, TCA_ID, CRD_SERIAL, CRD_RECHARGEABLE)
                    VALUES(@GFT_ID, 24, @TCA_ID, @CRD_SERIAL, 0) 
                END
                ELSE
                    SELECT
                            @GFT_ID = GFT_ID
                    FROM
                            DBO.T_CARD_CRD
                    WHERE
                            TCA_ID = @TCA_ID
                        AND    CRD_SERIAL = @CRD_SERIAL
            END
            ELSE
                IF LEFT(@BARCODE,2) = '22' --CHEQUE VARIABLE
                BEGIN
                    --CREATION DU CHEQUE S'IL N'EXISTE PAS
                    IF NOT EXISTS    (
                                    SELECT
                                            *
                                    FROM
                                            DBO.T_CHEQUE_CHQ
                                    WHERE
                                            CHQ_PREFIX = 22
                                        AND    CHQ_TYPE = @CHQ_TYPE
                                        AND    CHQ_YEAR = @CHQ_YEAR
                                        AND    CHQ_SERIAL = @CHQ_SERIAL
                                    )
                    BEGIN
                        INSERT INTO    DBO.T_GIFT_GFT DEFAULT VALUES;
                        SET @GFT_ID = SCOPE_IDENTITY();
     
                        DECLARE @CHQ_AMOUNT DECIMAL(6,2);
                        SET @CHQ_AMOUNT = CAST(@VALUE AS DECIMAL(6,2)) / 100;
                        INSERT INTO    DBO.T_CHEQUE_CHQ(GFT_ID, CHQ_PREFIX, CHQ_TYPE, CHQ_YEAR, CHQ_SERIAL, CHQ_AMOUNT)
                        VALUES(@GFT_ID, 22, @CHQ_TYPE, @CHQ_YEAR, @CHQ_SERIAL, @CHQ_AMOUNT);
                    END
                    ELSE
                        SELECT
                                @GFT_ID = GFT_ID
                        FROM
                                DBO.T_CHEQUE_CHQ
                        WHERE
                                CHQ_TYPE = @CHQ_TYPE
                            AND    CHQ_YEAR = @CHQ_YEAR
                            AND    CHQ_SERIAL = @CHQ_SERIAL
                END
    END
     
    GO
    Comme je m'attendais à ce que ce truc ne marche pas du premier coup, je note la ligne en cours de traitement dans la table T_CURRENT_PROCCESSING_LINE_CLP.

    Je sais donc exactement quelle ligne plante et j'ai voulu reproduire cette erreur en reprenant le même code que le step (avec le curseur en moins) et en initialisant les variables "manuellement" en faisant un select sur la ligne concernnée. Et là, pas de souci. Du coup, je ne comprends pas.

    J'ai cherché un peu partout où cette erreur pouvait se produire mais je ne trouve pas.

    D'autant plus que la ligne traitée juste avant celle défectueuse est exactement la même à l'exection de la valeur de la colonne BARCODE.

    Bref, je suis totalement perdu...
    Auriez-vous une idée vers quoi me diriger pour corriger cela ?

  2. #2
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Pour ma part, l'erreur se produit forcément dans la procédure stockée dont j'ai fourni le code car la table contenant la ligne en cours de traitement n'est pas mise à jour. Or, cette mise à jour se trouve juste après la procédure stockée (elle aurait en fait du être avant mais ce mauvais placement est finalement le bienvenu car il permet de localiser où se situe le problème).

    Cependant, j'ai exécuté la procédure stockée en passant en paramètre les valeurs de la ligne qui pose problème et elle fonctionne parfaitement.

    Quelle pourrait être la cause d'un comportement comme celui-ci ?

  3. #3
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par Kropernic Voir le message
    Comme je m'attendais à ce que ce truc ne marche pas du premier coup, je note la ligne en cours de traitement dans la table T_CURRENT_PROCCESSING_LINE_CLP.

    Je sais donc exactement quelle ligne plante et j'ai voulu reproduire cette erreur en reprenant le même code que le step (avec le curseur en moins) et en initialisant les variables "manuellement" en faisant un select sur la ligne concernnée. Et là, pas de souci. Du coup, je ne comprends pas.
    Est-ce que vous gérez une transaction ? dans ce cas l'insertion de la ligne "qui plante" peut être annulée lors de l'erreur, et la "dernière" ligne que vous voyez est en fait la dernière qui ait fonctionné.

    Une question :
    est-il normal que vous insériez CAST(@CHQ_TYPE AS DECIMAL(6,2)) dans la colonne CHQ_AMOUNT de votre table T_CHEQUE_CHQ ???

    pouvez vous poster la DDL de cette table ?

  4. #4
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Niveau transaction, je suis un noob... J'ai bien essayé mais j'obtenais des messages d'erreur que je ne comprenais pas. Du coup, pas de transaction. Enfin, pas de transaction explicite. Il n'est pas impossible qu'il y en ait qui soit implicite.

    Pour la question sur l'insertion, oui c'est normal.

    Dans le cas d'un gift dont le barcode commence par '21', je sais alors qu'il s'agit d'un gift cheque dont la valeur est égale au type. C.à.d. que les gift dont les barcodes commence par '2105' ont une valeur de 5€, ceux qui commence par '2110' ont une valeur de 10€, etc. où les 3e et 4e digit correspondent au type.

    Pour info, la ligne sur lequel s'est planté le step du job à comme valeur pour les colonnes BARCODE et VALUE respectivement '228880124526' et 1000.

    Avec cela, on arrive donc dans la dernière partie de procédure. Le préfixe 22 sur un barcode définissant un gift-cheque à valeur variable, j'ai donc le montant de cette valeur dans une variable. Ce qui n'est pas le cas pour les gift-cheque à valeur fixe (préfixe = '21') car elle est égale au type.

    C'est mal foutu... Mais c'est pour ça que j'importe tout dans une nouvelle DB ^^

  5. #5
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    J'oubliais !

    J'ai donc testé la procédure en créant sa petite soeur nommée UP_TEST dans laquelle j'ai remplacée les ordres d'insertion par des ordres de sélection sur les variables de la clause VALUES afin de voir si j'obtenais une valeur null pour la colonne CHQ_AMOUNT.

    Et ce ne fut pas le cas...

    Je sais bien que l'erreur arithmetic overflow se produit lorqu'on veut mettre un nombre dans une variable qui est trop grand pour le type de la variable.

    Mais y aurait-il d'autres cas ???

  6. #6
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Sorry pour le triple poste mais je me rends compte que j'ai oublié de poster le DDL de la table T_CHEQUE_CHQ. Le voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    USE [GIFT_MANAGEMENT]
    GO
     
    /****** Object:  Table [dbo].[T_CHEQUE_CHQ]    Script Date: 01/18/2013 12:12:29 ******/
    SET ANSI_NULLS ON
    GO
     
    SET QUOTED_IDENTIFIER ON
    GO
     
    SET ANSI_PADDING ON
    GO
     
    CREATE TABLE [dbo].[T_CHEQUE_CHQ](
        [GFT_ID] [int] NOT NULL,
        [CHQ_PREFIX] [tinyint] NOT NULL,
        [CHQ_TYPE] [tinyint] NOT NULL,
        [CHQ_YEAR] [tinyint] NOT NULL,
        [CHQ_SERIAL] [int] NOT NULL,
        [CHQ_AMOUNT] [decimal](6, 2) NOT NULL,
        [CHQ_CREATED_ON] [datetime] NOT NULL,
        [CHQ_CREATED_BY] [varchar](100) NOT NULL,
        [CHQ_MODIFIED_ON] [datetime] NULL,
        [CHQ_MODIFIED_BY] [varchar](100) NULL,
     CONSTRAINT [PK_T_CHEQUE_CHQ] PRIMARY KEY CLUSTERED 
    (
        [GFT_ID] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
     
    GO
     
    SET ANSI_PADDING OFF
    GO
     
    ALTER TABLE [dbo].[T_CHEQUE_CHQ]  WITH CHECK ADD  CONSTRAINT [FK_T_CHEQUE_CHQ_T_GIFT_GFT] FOREIGN KEY([GFT_ID])
    REFERENCES [dbo].[T_GIFT_GFT] ([GFT_ID])
    GO
     
    ALTER TABLE [dbo].[T_CHEQUE_CHQ] CHECK CONSTRAINT [FK_T_CHEQUE_CHQ_T_GIFT_GFT]
    GO
     
    ALTER TABLE [dbo].[T_CHEQUE_CHQ] ADD  DEFAULT (getdate()) FOR [CHQ_CREATED_ON]
    GO
     
    ALTER TABLE [dbo].[T_CHEQUE_CHQ] ADD  DEFAULT (suser_sname()) FOR [CHQ_CREATED_BY]
    GO

    EDIT :

    Pire ! Si je modifie le code du step pour qu'il reprenne à la ligne qui a planté, il continue le traitement avec succès pour quelques milliers de lignes et replante avec la même erreur et toujours apparemment sans raison... Du moins, je ne vois pas...

  7. #7
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par Kropernic Voir le message
    Pire ! Si je modifie le code du step pour qu'il reprenne à la ligne qui a planté, il continue le traitement avec succès pour quelques milliers de lignes et replante avec la même erreur et toujours apparemment sans raison... Du moins, je ne vois pas...
    Êtes-vous sûr qu'il reprend à la ligne qui a planté ?

    Peut être pouvez vous placer votre code (le script principal) dans SSMS, l'entourer d'un try catch avec un point d’arrêt dans le catch... on pourra peut être mieux localiser l'erreur

    Une autre piste : ça plante pendant le fetch. Dans ce cas, certaines variables auront les valeurs de la ligne qui plante, les autres (située après la variable posant problème, ainsi qu'elle même) auront les valeurs de la ligne précédente, ça pourrait perturber le traitement, ainsi que l'analyse du bug. Pouvez vous nous poster le DDL de la table T_CHEQUE_ACHAT_HISTORY

  8. #8
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Personne n'aurait une petite idée de où et cette procédure pourrait générer un arithmetic overflow ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    USE [GIFT_MANAGEMENT]
    GO
     
    /****** Object:  StoredProcedure [dbo].[TMP_UP_CREATE_GIFT_IF_NOT_EXISTS]    Script Date: 01/18/2013 10:28:14 ******/
    SET ANSI_NULLS ON
    GO
     
    SET QUOTED_IDENTIFIER ON
    GO
     
     
    CREATE PROCEDURE [dbo].[TMP_UP_CREATE_GIFT_IF_NOT_EXISTS]
        @BARCODE    CHAR(13),
        @GFT_ID        INT OUTPUT,
        @VALUE        INT = NULL
    AS
    BEGIN
        SET NOCOUNT ON;
        SET ANSI_WARNINGS OFF;
     
        DECLARE @TCA_ID        SMALLINT = 0;
        DECLARE @TCA_CODE    SMALLINT = CAST(SUBSTRING(@BARCODE,3,3) AS SMALLINT);
        DECLARE @CRD_SERIAL    INT    = CAST(SUBSTRING(@BARCODE,6,7) AS INT);
     
        DECLARE @CHQ_TYPE    TINYINT = CAST(SUBSTRING(@BARCODE,3,2) AS TINYINT);
        DECLARE @CHQ_YEAR    TINYINT = CAST(SUBSTRING(@BARCODE,5,1) AS TINYINT);
        DECLARE @CHQ_SERIAL INT = CAST(SUBSTRING(@BARCODE,6,7) AS INT);
     
        IF LEFT(@BARCODE,2) = '21' --CHEQUE
        BEGIN
            --CREATION DU CHEQUE S'IL N'EXISTE PAS
            IF NOT EXISTS    (
                            SELECT
                                    *
                            FROM
                                    DBO.T_CHEQUE_CHQ
                            WHERE
                                    CHQ_PREFIX = 21
                                AND    CHQ_TYPE = @CHQ_TYPE
                                AND    CHQ_YEAR = @CHQ_YEAR
                                AND    CHQ_SERIAL = @CHQ_SERIAL
                            )
            BEGIN
                INSERT INTO    DBO.T_GIFT_GFT DEFAULT VALUES;
                SET @GFT_ID = SCOPE_IDENTITY();
     
                INSERT INTO    DBO.T_CHEQUE_CHQ(GFT_ID, CHQ_PREFIX, CHQ_TYPE, CHQ_YEAR, CHQ_SERIAL, CHQ_AMOUNT)
                VALUES(@GFT_ID, 21, @CHQ_TYPE, @CHQ_YEAR, @CHQ_SERIAL, CAST(@CHQ_TYPE AS DECIMAL(6,2)));
            END
            ELSE
                SELECT
                        @GFT_ID = GFT_ID
                FROM
                        DBO.T_CHEQUE_CHQ
                WHERE
                        CHQ_TYPE = @CHQ_TYPE
                    AND    CHQ_YEAR = @CHQ_YEAR
                    AND    CHQ_SERIAL = @CHQ_SERIAL
        END
        ELSE
            IF LEFT(@BARCODE,2) = '24' --CARTE
            BEGIN
                --CREATION DU TYPE DE CARTE S'IL N'EXISTE PAS
                IF NOT EXISTS    (
                                SELECT
                                        *
                                FROM
                                        DBO.T_TYPE_CARD_TCA
                                WHERE
                                        TCA_CODE = @TCA_CODE
                                )
                BEGIN
                    INSERT INTO    DBO.T_TYPE_CARD_TCA(TCA_STANDARD, TCA_CODE)
                    VALUES(0, @TCA_CODE);
                    SET @TCA_ID = SCOPE_IDENTITY();
                END
                ELSE
                    SELECT    
                            @TCA_ID = TCA_ID
                    FROM
                            DBO.T_TYPE_CARD_TCA
                    WHERE
                            TCA_CODE = @TCA_CODE
     
                --CREATION DE LA CARTE SI ELLE N'EXISTE PAS
                IF NOT EXISTS    (
                                SELECT
                                        *
                                FROM
                                        DBO.T_CARD_CRD
                                WHERE
                                        TCA_ID = @TCA_ID
                                    AND    CRD_SERIAL = @CRD_SERIAL
                                )
                BEGIN
                    INSERT INTO DBO.T_GIFT_GFT DEFAULT VALUES;
                    SET @GFT_ID = SCOPE_IDENTITY();
     
                    INSERT INTO DBO.T_CARD_CRD(GFT_ID, CRD_PREFIX, TCA_ID, CRD_SERIAL, CRD_RECHARGEABLE)
                    VALUES(@GFT_ID, 24, @TCA_ID, @CRD_SERIAL, 0) 
                END
                ELSE
                    SELECT
                            @GFT_ID = GFT_ID
                    FROM
                            DBO.T_CARD_CRD
                    WHERE
                            TCA_ID = @TCA_ID
                        AND    CRD_SERIAL = @CRD_SERIAL
            END
            ELSE
                IF LEFT(@BARCODE,2) = '22' --CHEQUE VARIABLE
                BEGIN
                    --CREATION DU CHEQUE S'IL N'EXISTE PAS
                    IF NOT EXISTS    (
                                    SELECT
                                            *
                                    FROM
                                            DBO.T_CHEQUE_CHQ
                                    WHERE
                                            CHQ_PREFIX = 22
                                        AND    CHQ_TYPE = @CHQ_TYPE
                                        AND    CHQ_YEAR = @CHQ_YEAR
                                        AND    CHQ_SERIAL = @CHQ_SERIAL
                                    )
                    BEGIN
                        INSERT INTO    DBO.T_GIFT_GFT DEFAULT VALUES;
                        SET @GFT_ID = SCOPE_IDENTITY();
     
                        DECLARE @CHQ_AMOUNT DECIMAL(6,2);
                        SET @CHQ_AMOUNT = CAST(@VALUE AS DECIMAL(6,2)) / 100;
                        INSERT INTO    DBO.T_CHEQUE_CHQ(GFT_ID, CHQ_PREFIX, CHQ_TYPE, CHQ_YEAR, CHQ_SERIAL, CHQ_AMOUNT)
                        VALUES(@GFT_ID, 22, @CHQ_TYPE, @CHQ_YEAR, @CHQ_SERIAL, @CHQ_AMOUNT);
                    END
                    ELSE
                        SELECT
                                @GFT_ID = GFT_ID
                        FROM
                                DBO.T_CHEQUE_CHQ
                        WHERE
                                CHQ_TYPE = @CHQ_TYPE
                            AND    CHQ_YEAR = @CHQ_YEAR
                            AND    CHQ_SERIAL = @CHQ_SERIAL
                END
    END
     
    GO
    J'ai beau retourné dans tout les sens, je ne vois pas...
    Au niveau des paramètres, je passe exactement le même type de variable. Le problème n'est donc pas là.

    J'ai pensé au découpage du barcode mais pareil, un tinyint allant de 0 à 255, en prenant 2 digit du barcode, j'ai de la marge...

    Le message d'erreur parle de CHQ_AMOUNT, j'ai donc regardé de ce côté mais tous les casts que je fais pour traiter la valeur que je mets dans cette colonne semblent fonctionner...

    Please help

  9. #9
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par Kropernic Voir le message
    Personne n'aurait une petite idée de où et cette procédure pourrait générer un arithmetic overflow ?
    peut être ici ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     SET @ORIGIN = @ORIGIN * 10000
    quel est le type de votre colonne ORIGIN ?
    et que donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT
            CAST(CAST(ORIGIN AS INT) * 10000 AS INT)
    FROM
            DBO.T_CHEQUE_ACHAT_HISTORY
    WHERE
            ACTION = 'T'
    J'ai pensé au découpage du barcode mais pareil, un tinyint allant de 0 à 255, en prenant 2 digit du barcode, j'ai de la marge...
    sauf si votre barcode contient un moins !

  10. #10
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    peut être ici ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     SET @ORIGIN = @ORIGIN * 10000
    quel est le type de votre colonne ORIGIN ?
    La colonne est de type INT. J'y ai pensé bien sûr. Mais pour les cas qui sont traités par ce step, le nombre dans origin est TOUJOURS au maximum sur 2 digits.
    Pour info, voici la ligne une ligne qui provoque l'erreur :
    SeqNrHist = 1070031
    Barcode = 228880082806
    DatTim = 2007-08-04 17:13:00.000
    Action = T
    Origin =17
    DestType = 3
    Dest = 410067
    Value = 2500
    SaleType = 0
    UserType = 0
    (edit : mise en relation des colonnes et de leur valeur)

    Citation Envoyé par aieeeuuuuu Voir le message
    et que donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT
            CAST(CAST(ORIGIN AS INT) * 10000 AS INT)
    FROM
            DBO.T_CHEQUE_ACHAT_HISTORY
    WHERE
            ACTION = 'T'
    Et donc ceci ne donne bien sûr aucune erreur vu que l'entier est toujours inférieur à 100. Donc même en multipliant par 10000, on a est encore loin des 2 milliards ^^.

    Citation Envoyé par aieeeuuuuu Voir le message
    sauf si votre barcode contient un moins !
    Ca je n'y avait pas pensé... C'est vrai que, du point de vue du type de donnée, rien ne l'interdit. Heureusement, ce n'est jamais le cas. Dans l'exemple que j'ai donné plus haut, il y a un barcode.
    Il s'agit d'un EAN13 sans le check digit. Donc pas de signe dans le barcode.

    Toujours avec la ligne donnée plus haut, on voit que je mets dans des tinyint les valeurs 88 et 8. C'est donc bien dans la plage de donnée de ce type.

    Pareil pour la valeur ou je caste 2500 en decimal(6,2) et que je divise par 100 après.

    ... divisé un décimal par un entier... Pas top ça maintenant que j'y pense...

    Pourtant, si je fais un exec de la procédure stockée en passant le barcode et la valeur, elle ne donne aucune erreur... Y aurait-il une différence de tolérance entre un job et un script exécuté dans SSMS ?

  11. #11
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Est-il normal que d'un côté vous fassiez :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     CAST(@CHQ_TYPE AS DECIMAL(6,2)));
    et de l'autre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    DECLARE @CHQ_AMOUNT DECIMAL(6,2);
                        SET @CHQ_AMOUNT = CAST(@VALUE AS DECIMAL(6,2)) / 100;
    ?

  12. #12
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Malheureusement oui.

    Cette ancienne DB ne respecte même pas la 1NF... En fait, c'est même pire que ça. Si je ne me trompe pas, la 1NF dit que chaque colonne doit être atomique. Ici, en plus de ne pas être atomique, une colonne contient dans certains cas un numéro de caisse et un numéro de ticket, et dans d'autre, il contient une date au format YYMMDD. Bref, la joie quoi !

    Alors oui, il y a une colonne VALUE mais elle n'est pas toujours remplie... (parfois à 0). Alors pour les gifts ou il est possible de déterminer la valeur via leur barcode (cas pour les gift-cheques commençant par '21'), j'utilise ce procédé pour ne pas devoir tester si la colonne VALUE est à 0 ou non.

    Pour les gift-cheques commençant par '22', comme on ne peut déterminer leur valeur via le barcode, ils ont quand même eu le bon goût de toujours mettre quelque chose dans la colonne VALUE.

    Ce qui explique que, dans certains cas, je fais un cast de CHQ_TYPE et dans d'autre, j'utilise la donnée passée en paramètre pour insérer une valeur dans la colonne CHQ_AMOUNT.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Arithmetic Overflow error
    Par Guigsounet dans le forum Développement
    Réponses: 2
    Dernier message: 08/06/2015, 17h37
  2. GetDate() et arithmetic overflow error
    Par sylvaine dans le forum Outils
    Réponses: 5
    Dernier message: 11/06/2010, 11h48
  3. [SQSH] Arithmetic overflow
    Par ecerisier dans le forum Outils
    Réponses: 9
    Dernier message: 08/11/2007, 17h12
  4. #8115 Arithmetic overflow error
    Par dev_Elo dans le forum Access
    Réponses: 3
    Dernier message: 06/02/2007, 14h49
  5. Réponses: 3
    Dernier message: 16/09/2004, 14h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo