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

MS SQL Server Discussion :

Insert en table bizarre


Sujet :

MS SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 60
    Par défaut Insert en table bizarre
    Bonjour,

    je rencontre un problème plus que bizarre (ou tout simplement évident , au choix)

    Voilà, depuis que j'ai codé des triggers (insert, update et delete) sur une table, lorsque j'insert une ligne tout à fait normale, la mise à jour de la ligne est corrompue (dixit Management Studio). Après un Requery, ma ligne apparait bien.
    Bon, le fait d'ajouter un trigger qui fait que l'insert fonctionne différemment serait une explication logique et me conviendrait malgré tout, mais il y a plus grave.

    Dans mon appli, je me connecte grâce à ADO et le pilote natif SQL Server 2005, et lorsque je fait un 'insert into ...' et que je lit la propriété RowsAffected, j'ai un joli zéro !!!
    inutile de vous dire qu'avant le trigger j'avais pas 0

    Alors que faire ???

  2. #2
    Membre Expert
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Par défaut
    Bonjour,

    Essaie de mettre au début de ton trigger.

  3. #3
    Rédacteur/Modérateur

    Avatar de Fabien Celaia
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    4 228
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 4 228
    Billets dans le blog
    25
    Par défaut
    et de nous poster le code du trigger et de la table pour repro
    Sr DBA Oracle / MS-SQL / MySQL / Postgresql / SAP-Sybase / Informix / DB2

    N'oublie pas de consulter mes articles, mon blog, les cours et les FAQ SGBD

    Attention : pas de réponse technique par MP : pensez aux autres, passez par les forums !

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 60
    Par défaut
    OK, voilà le code du trigger :

    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
    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    go
    -- =============================================
    -- Author:        Frédéric Croisé
    -- Create date: 22/06/2006
    -- Description:    TRIGGER à l'insertion dans t_pallet pour t_mvt
    -- =============================================
    ALTER TRIGGER [SCAW_t_pallet_INS]
       ON [dbo].[t_pallet]
       FOR INSERT
    NOT FOR REPLICATION
    AS 
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
     
        DECLARE @user_insert AS varchar(50)
        DECLARE @user_application AS char(1)
        DECLARE @mvt_type AS varchar(10)
        DECLARE @mvt_ok as bit
        SET @mvt_type='DEF_INS'
        SET @mvt_ok=0
     
        --On récupère le nom de l'utilisateur et de l'application
        SELECT  @user_application = ISNULL(dbo.t_users.user_appli,'D'), 
            @user_insert = ISNULL(dbo.t_users.user_display,'DEFAULT')
        FROM    dbo.t_users INNER JOIN
        dbo.t_session ON dbo.t_users.user_name = dbo.t_session.user_name
        WHERE   dbo.t_session.user_spid = @@spid
        ORDER BY date_session;
     
        --INVIRTUAL
        --On vérifie si on met à jour le virtual à 'O'
        IF UPDATE(virtual)
        BEGIN
            DECLARE @virtual_insert AS char(1)
            SELECT @virtual_insert = UPPER(virtual)
            FROM inserted;
     
            IF @virtual_insert='O'
            BEGIN
                SET @mvt_type='INVIRTUAL'
                SET @mvt_ok=1
            END
        END
     
        --INRETURN
        --On vérifie si on est dans le cas d'un retour 
        IF (@mvt_ok=0)
        BEGIN
            --On vérifie si le sscc est dans t_pallet_file
            SELECT dbo.t_pallet_file.sscc
            FROM inserted, dbo.t_pallet_file 
            WHERE (inserted.sscc = dbo.t_pallet_file.sscc)
     
            IF @@ROWCOUNT>0
            BEGIN
                SET @mvt_type='INRETURN'
                SET @mvt_ok=1
            END
        END
     
        --INPICK
        --On vérifie si on est dans le cas d'un picking
        IF (@mvt_ok=0)
        BEGIN
            --On vérifie dans t_sscc
            SELECT dbo.t_sscc.sscc
            FROM dbo.t_sscc, inserted
            WHERE dbo.t_sscc.sscc = inserted.sscc
     
            IF @@ROWCOUNT>0
            BEGIN
                SET @mvt_type='INPICK'
                SET @mvt_ok=1
            END
     
        END
     
        --INMAN | INRECEPT | INRECAUTO
        --On vérifie si on est dans le cas d'une insertion manuel
        --On vérifie si on est dans le cas d'une réception
        IF (@mvt_ok=0)
        BEGIN
            --On vérifie si le scc n'est pas dans t_recadv_lines
            SELECT dbo.t_recadv_lines.sscc
            FROM inserted, dbo.t_recadv_lines
            WHERE (inserted.sscc = dbo.t_recadv_lines.sscc)
     
            IF @@ROWCOUNT=0 --Le sscc n'est pas dans t_recadv_lines
            BEGIN
                SET @mvt_type='INMAN'
            END
            ELSE --Le sscc est dans t_recadv_lines
            BEGIN
                --On attribue le type en fonction de l'application
                IF @user_application='T'
                BEGIN
                    SET @mvt_type='INRECEPT'
                END    
                ELSE IF @user_application='M'
                BEGIN
                    SET @mvt_type='INRECAUTO'
                END
            END
        END
     
        --On insere dans t_mvt
        INSERT INTO t_mvt(type_mvt, sscc, product, qty_before, qty_mvt, qty_after, user_mvt, platform, appli_mvt)
        SELECT @mvt_type, sscc, dun14, dbo.FS_qty_product(dun14,platform)-qty, 
            qty, dbo.FS_qty_product(dun14,platform), @user_insert, platform, @user_application
        FROM inserted
     
    END
    il est tel quel dans ma base...

    et le descriptif de la table t_pallet :

    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
    USE [SCAWMDB]
    GO
    /****** Objet :  Table [dbo].[t_pallet]    Date de génération du script : 07/03/2006 17:09:25 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_PADDING ON
    GO
    CREATE TABLE [dbo].[t_pallet](
        [sscc] [char](18) COLLATE French_CI_AS NOT NULL,
        [dun14] [char](14) COLLATE French_CI_AS NOT NULL,
        [batch] [varchar](50) COLLATE French_CI_AS NOT NULL,
        [dlc] [smalldatetime] NOT NULL,
        [qty] [int] NOT NULL,
        [unified] [char](1) COLLATE French_CI_AS NOT NULL CONSTRAINT [DF_t_pallet_unified]  DEFAULT ('1'),
        [date_creation] [datetime] NOT NULL CONSTRAINT [DF_t_pallet_date_creation]  DEFAULT (getdate()),
        [state] [char](3) COLLATE French_CI_AS NOT NULL CONSTRAINT [DF_t_pallet_blocked]  DEFAULT ('OK'),
        [created] [char](1) COLLATE French_CI_AS NOT NULL CONSTRAINT [DF_t_pallet_created]  DEFAULT ('N'),
        [platform] [char](13) COLLATE French_CI_AS NOT NULL,
        [virtual] [char](1) COLLATE French_CI_AS NOT NULL CONSTRAINT [DF_t_pallet_virtual]  DEFAULT ('N'),
        [msrepl_tran_version] [uniqueidentifier] NOT NULL CONSTRAINT [MSrepl_tran_version_default_B4659F02_4F04_4A11_8812_4B0320BEC670_2043154324]  DEFAULT (newid()),
     CONSTRAINT [PK_t_pallet] PRIMARY KEY CLUSTERED 
    (
        [sscc] ASC,
        [dun14] ASC,
        [batch] ASC,
        [dlc] ASC,
        [qty] ASC,
        [date_creation] ASC,
        [platform] ASC
    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
     
    GO
    SET ANSI_PADDING OFF
    Comme vous pouvez le remarquer, c'est une table répliquée.

    et tant qu'à faire le code la base de données : (j'ai enlevé les 'GO' pour la lisibilité)

    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
    USE [master]
    /****** Objet :  Database [SCAWMDB]    Date de génération du script : 07/03/2006 17:11:37 ******/
    CREATE DATABASE [SCAWMDB] ON  PRIMARY 
    ( NAME = N'SCAWMDB', FILENAME = N'd:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\SCAWMDB.mdf' , SIZE = 22080KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%)
     LOG ON 
    ( NAME = N'SCAWMDB_log', FILENAME = N'd:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\SCAWMDB_log.ldf' , SIZE = 388544KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
     COLLATE French_CI_AS
    EXEC dbo.sp_dbcmptlevel @dbname=N'SCAWMDB', @new_cmptlevel=90
    IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
    begin
    EXEC [SCAWMDB].[dbo].[sp_fulltext_database] @action = 'disable'
    end
    ALTER DATABASE [SCAWMDB] SET ANSI_NULL_DEFAULT OFF 
    ALTER DATABASE [SCAWMDB] SET ANSI_NULLS OFF 
    ALTER DATABASE [SCAWMDB] SET ANSI_PADDING OFF 
    ALTER DATABASE [SCAWMDB] SET ANSI_WARNINGS OFF 
    ALTER DATABASE [SCAWMDB] SET ARITHABORT OFF 
    ALTER DATABASE [SCAWMDB] SET AUTO_CLOSE OFF 
    ALTER DATABASE [SCAWMDB] SET AUTO_CREATE_STATISTICS ON 
    ALTER DATABASE [SCAWMDB] SET AUTO_SHRINK OFF 
    ALTER DATABASE [SCAWMDB] SET AUTO_UPDATE_STATISTICS ON 
    ALTER DATABASE [SCAWMDB] SET CURSOR_CLOSE_ON_COMMIT OFF 
    ALTER DATABASE [SCAWMDB] SET CURSOR_DEFAULT  GLOBAL 
    ALTER DATABASE [SCAWMDB] SET CONCAT_NULL_YIELDS_NULL OFF 
    ALTER DATABASE [SCAWMDB] SET NUMERIC_ROUNDABORT OFF 
    ALTER DATABASE [SCAWMDB] SET QUOTED_IDENTIFIER OFF 
    ALTER DATABASE [SCAWMDB] SET RECURSIVE_TRIGGERS OFF 
    ALTER DATABASE [SCAWMDB] SET  DISABLE_BROKER 
    ALTER DATABASE [SCAWMDB] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
    ALTER DATABASE [SCAWMDB] SET DATE_CORRELATION_OPTIMIZATION OFF 
    ALTER DATABASE [SCAWMDB] SET TRUSTWORTHY OFF 
    ALTER DATABASE [SCAWMDB] SET ALLOW_SNAPSHOT_ISOLATION OFF 
    ALTER DATABASE [SCAWMDB] SET PARAMETERIZATION SIMPLE 
    ALTER DATABASE [SCAWMDB] SET  READ_WRITE 
    ALTER DATABASE [SCAWMDB] SET RECOVERY FULL 
    ALTER DATABASE [SCAWMDB] SET  MULTI_USER 
    ALTER DATABASE [SCAWMDB] SET PAGE_VERIFY CHECKSUM  
    ALTER DATABASE [SCAWMDB] SET DB_CHAINING OFF
    Voilà ! bonne lecture, j'espère au moins que ça va vous servir...

    Merci d'avance.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 60
    Par défaut
    Bon, je vois que ça ne vous inspire pas beaucoup.

    Après beaucoup de tests, je m'aperçoit que mon appli cliente (en Delphi) récupérait après ExecSQL, un 0 ou 1 selon un résultat d'un select dans le trigger.
    Il semble donc que "set nocount on" n'a pas d'effet. De plus mettre "no count off" a exactement le même comportement.
    j'ai ensuite ajouter "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;", mais rien n'y fait. Ni d'autres niveaux d'isolation d'ailleurs.

    Je ne sais plus trop quoi faire, à part ne pas tester le retour de mon ExecSQL, ce qui m'embête sérieusement pour la fiabilité de mon programme.

    J'ai beau chercher dans la doc, je ne trouve rien d'extra, sauf dans la doc de la syntaxe de CREATE TRIGGER où il est écrit:
    " Un déclencheur qui inclut soit des instructions SELECT qui renvoient des résultats à l'utilisateur, soit des instructions exécutant des affectations de variables, doit être traité de manière particulière."
    Aussitôt lu, aussitôt essayé : j'ai placer 'select 1' à la fin de mon trigger avec "set nocount off", mais rien n'y fait !!! j'ai toujours 0 ou 1 en fonction d'un autre select antérieur.

    Je n'y comprends plus rien.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 60
    Par défaut
    J'ai trouvé mieux que ça !!!!

    j'ai mis "select count(*) from inserted" au tout début de mon trigger.

    au retour j'obtiens -1 !!! oui môssieur
    c'est pas mal quand même, essayez de faire mieux

    bon, je crois que SQL server et Delphi ne sont pas tout à fait compatible, malheureusement je pas le temps d'essayer avec un autre environnement...

    A+

    Peck777

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

Discussions similaires

  1. Insertion dans table SQL server (Trigger) Aidz moi SVP????
    Par pop bob dans le forum Développement
    Réponses: 2
    Dernier message: 30/07/2005, 23h55
  2. insert into table values/ insert into table select
    Par aaronw dans le forum Requêtes
    Réponses: 4
    Dernier message: 31/05/2005, 15h14
  3. Réponses: 3
    Dernier message: 11/01/2005, 08h20
  4. Réponses: 3
    Dernier message: 19/11/2004, 21h48
  5. [debutant] select-insert sur tables de bases differentes
    Par RedMax dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 21/10/2004, 18h59

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