Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Compteur

18 réponses
Avatar
Gloops
Bonjour tout le monde,

Pardonnez le niveau de la question, mais j'ai modifi=E9 un champ entier=20
pour y cr=E9er un compteur, et dans un nouvel enregistrement je m'aper=E7=
ois=20
que sa valeur par d=E9faut est toujours Null. Pour une cl=E9 primaire, c'=
est=20
g=EAnant. Est-ce moi qui n'ai pas assur=E9 ?

Pendant que je suis l=E0 : auriez-vous une bonne adresse (de site web,=20
peut-=EAtre) =E0 me conseiller pour (quasiment) d=E9marrer sur l'=E9tude =
de TSQL=20
? Avant de me rendre compte que le moyen =E9tait probablement=20
surdimensionn=E9, j'ai essay=E9 de cr=E9er un trigger, pour lors de la=20
cr=E9ation d'un enregistrement, donner au champ num=E9ro la valeur=20
MAX(Numero) + 1. Le seul commentaire que m'a fait le syst=E8me (en fait=20
SSMSE) est que la formule n'=E9tait pas bonne. Bon, je veux bien, moi. Si=
=20
il y avait moyen de d=E9velopper un peu ... Dans l'aide, le sommaire est =

int=E9ressant : je ne trouve gu=E8re que l'aide de l'aide, en Fran=E7ais =
et en=20
Anglais.

Ah au fait si je veux que l'utilisateur puisse modifier les valeurs des=20
num=E9ros, apr=E8s coup, finalement le trigger serait mieux que le compte=
ur,=20
peut-=EAtre ?

10 réponses

1 2
Avatar
Gloops
Gloops a écrit, le 10/12/2009 19:16 :
Bonjour tout le monde,

Pardonnez le niveau de la question, mais j'ai modifié un champ entier
pour y créer un compteur, et dans un nouvel enregistrement je m'aperç ois
que sa valeur par défaut est toujours Null. Pour une clé primaire, c'est
gênant. Est-ce moi qui n'ai pas assuré ?




J'avoue que je me surpasse : le compteur reste nul tant que
l'enregistrement est nouveau, puis il est initialisé lorsqu'on valide
l'enregistrement. Au passage, je vois là la résolution d'une faibless e
que je connais sous Access, à savoir que si on tente trois fois de suit e
de créer un enregistrement et qu'on change d'avis à chaque fois, le
compteur a avancé de trois. Sous SQL Server, me semble-t-il, non.
Avatar
EmanuelL
Salut Gloops,

Pour la documentation de T-SQL, regardes ici :
http://sqlpro.developpez.com/

Peux-tu nous mettre le script de la création de cette table?

A+ ;-)

Gloops a formulé ce jeudi :
Gloops a écrit, le 10/12/2009 19:16 :
Bonjour tout le monde,

Pardonnez le niveau de la question, mais j'ai modifié un champ entier pour
y créer un compteur, et dans un nouvel enregistrement je m'aperçois que sa
valeur par défaut est toujours Null. Pour une clé primaire, c'est gênant.
Est-ce moi qui n'ai pas assuré ?




J'avoue que je me surpasse : le compteur reste nul tant que l'enregistrement
est nouveau, puis il est initialisé lorsqu'on valide l'enregistrement. Au
passage, je vois là la résolution d'une faiblesse que je connais sous Access,
à savoir que si on tente trois fois de suite de créer un enregistrement et
qu'on change d'avis à chaque fois, le compteur a avancé de trois. Sous SQL
Server, me semble-t-il, non.



--

*!* -----------------------------------
EmanuelL
Membre d'AtoutFox
www.atoutfox.org
Avatar
Gloops
EmanuelL a écrit, le 11/12/2009 23:30 :
Salut Gloops,

Pour la documentation de T-SQL, regardes ici :
http://sqlpro.developpez.com/



En effet, peut-être pas vraiment spécifique à T-SQL toutefois ?

Alors j'ai mis ça en ½uvre :

CREATE TRIGGER TRG_INS_BEF_SitesRech
ON dbo.tabSitesRecherche
UPDATE NEW
SET Numero = MAX(Numero) + 1

et je me fais jeter :
Msg 156, Niveau 15, État 1, Procédure TRG_INS_BEF_SitesRech, Ligne 3
Incorrect syntax near the keyword 'UPDATE'.

Si je mets le curseur sur NEW et que j'appuie sur F1, je me retrouve
avec l'aide du mot-clef new dans le langage C++, alors qu'habituellement
je développe en C# et que j'ai paramétré MSDN en conséquence.

Du coup j'apprécie particulièrement le sommaire de l'aide, divisé e n
deux rubriques principales :
- aide sur l'aide
- help on help

Peut-être vais-je devoir effectivement chercher là-dedans ce qui a
évolué, pour pouvoir arriver sur l'aide de T-SQL.

En partant de UPDATE j'arrive bien dans l'aide de T-SQL, mais les
paramètres de UPDATE ne comportent pas de mot-clef NEW, ce qui
vraisemblablement explique qu'on me retourne une erreur dessus.
D'ailleurs, j'avais lu l'aide de UPDATE avant de poser ma question.
Pas assez attentivement peut-être ?


Peux-tu nous mettre le script de la création de cette table?



//sans le compteur :

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tabSitesRecherche](
[Numero] [int] IDENTITY(1,1) NOT NULL,
[NomSite] [nchar](40) NULL,
[AvantArgu] [nchar](60) NULL,
[ApresArgu] [nchar](60) NULL,
CONSTRAINT [PK_tabSitesRecherche] PRIMARY KEY CLUSTERED
(
[Numero] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KE Y =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Avatar
Gloops
Gloops a écrit, le 12/12/2009 13:44 :
Alors j'ai mis ça en ½uvre :

CREATE TRIGGER TRG_INS_BEF_SitesRech
ON dbo.tabSitesRecherche
UPDATE NEW
SET Numero = MAX(Numero) + 1



Ah oui non mais bien entendu j'en ai oublié en route, aussi, puisqu'il
manque le BEFORE INSERT, et justement si je regarde l'aide du CREATE
TRIGGER je confirme l'intérêt d'une doc spécifique à TSQL, puiqu' il faut
mettre FOR INSERT.

J'ai pu créer le trigger comme ceci :
USE [Tests]
GO
CREATE TRIGGER TRG_SITESRECH1
ON [dbo].[tabSitesRecherche]
FOR INSERT
AS
UPDATE NEW
SET Numero = MAX(Numero) + 1

Apparemment, ça ne donne rien si je ne mets rien dans le champ Numero e n
créant un nouvel enregistrement, j'essaie avec 0, du coup on me dit que
les données de la ligne n'ont pas été enregistrées, source d'erre ur .Net
SqlClient DataProvider, message d'erreur "Invalid object name 'NEW'".

Si j'essaie de modifier le trigger en enlevant le mot NEW ça ne passe p as.
Avatar
Gloops
La requête de création passe avec un UPDATE normal, à savoir
AS
UPDATE dbo.tabSitesRecherche
SET Numero = 15

ça coince si je veux mettre SET Numero = MAX(Numero) + 1
An aggregate may not appear in the set list of an UPDATE statement.
Bon, j'imagine qu'il faudra parcourir la table en évaluant le maximum
avec une variable scalaire.

Le but du NEW était de ne faire porter la mise à jour que sur le nouv el
enregistrement, sinon à l'exécution de ce que j'ai mis ci-dessus on m e
reproche des clefs dupliquées, ce qui veut donc dire qu'on a appliqué la
mise à jour à toute la table. Alors si je mets un WHERE, je mets quoi
derrière ?

Ah, quelque chose d'intéressant :
AS
UPDATE inserted
SET Numero = 15

Msg 286, Niveau 16, État 1, Procédure TRG_SITESRECH1, Ligne 5
The logical tables INSERTED and DELETED cannot be updated.

Le coup de grâce ?
Ou une invitation à passer plutôt par AFTER INSERT, peut-être ?
Avatar
Michel LEVY
Bonjour,

un petit coup d'½il sur IDENTITY dans l'aide te permettrait probablement de
comprendre ton erreur, de même que la lecture du lien qu'Emanuel t'a donné

--
Michel Lévy
--

"Gloops" a écrit dans le message de groupe de
discussion :
La requête de création passe avec un UPDATE normal, à savoir
AS
UPDATE dbo.tabSitesRecherche
SET Numero = 15

ça coince si je veux mettre SET Numero = MAX(Numero) + 1
An aggregate may not appear in the set list of an UPDATE statement.
Bon, j'imagine qu'il faudra parcourir la table en évaluant le maximum avec
une variable scalaire.

Le but du NEW était de ne faire porter la mise à jour que sur le nouvel
enregistrement, sinon à l'exécution de ce que j'ai mis ci-dessus on me
reproche des clefs dupliquées, ce qui veut donc dire qu'on a appliqué la
mise à jour à toute la table. Alors si je mets un WHERE, je mets quoi
derrière ?

Ah, quelque chose d'intéressant :
AS
UPDATE inserted
SET Numero = 15

Msg 286, Niveau 16, État 1, Procédure TRG_SITESRECH1, Ligne 5
The logical tables INSERTED and DELETED cannot be updated.

Le coup de grâce ?
Ou une invitation à passer plutôt par AFTER INSERT, peut-être ?



Avatar
Gloops
A défaut peut-être d'avoir fait quelque chose de très orthodoxe, su r
quoi quelqu'un m'apportera peut-être un éclairage, j'ai écrit quelq ue
chose qui fonctionne.

Je mets d'abord 0 comme valeur par défaut du champ Numero, puis je cré e
le trigger suivant :

USE [Tests]
GO
CREATE TRIGGER TRG_SITESRECH1
ON dbo.tabSitesRecherche
AFTER INSERT
AS
DECLARE @NB INT
SELECT @NB = MAX(Numero) FROM dbo.tabSitesRecherche
UPDATE dbo.tabSitesRecherche
SET Numero = @NB + 1
WHERE Numero = 0

Le nouveau numéro n'est visible qu'en rafraichissant la requête de
sélection, mais il correspond bien à un de plus que le maximum prée xistant.

Il est entendu que l'utilisateur doit s'abstenir de la fantaisie
d'affecter la valeur 0 à Numero sur une ligne, sinon à la prochaine
création de ligne il se fait rembarrer pour cause de doublon. J'imagine
qu'il ne se trouvera pas grand-monde pour s'offusquer qu'on ne puisse
pas mettre 0 comme numéro. Peut-être devrais-je créer un deuxième
Trigger, sur UPDATE, pour rappeler l'utilisateur à l'ordre si il se
laisse aller de ce côté.
Avatar
Gloops
Michel LEVY a écrit, le 12/12/2009 16:02 :
Bonjour,

un petit coup d'½il sur IDENTITY dans l'aide te permettrait probablem ent
de comprendre ton erreur, de même que la lecture du lien qu'Emanuel t 'a
donné




Effectivement, mon erreur est que la requête de création de table que
j'ai indiquée a manifestement été générée avant la suppressio n du
compteur (j'ai dû oublier de demander la sauvegarde).

Je suis parti du lien d'Emmanuel, puis j'ai adapté à TSQL, par exempl e
pour BEFORE INSERT à remplacer par FOR INSERT, de toute façon il est
vrai que j'ai fini par m'orienter vers AFTER INSERT qui met tout le
monde d'accord puisque la syntaxe est la même des deux côtés.

Un point de repère intéressant : une fois qu'on a trouvé dans MSDN une
des rubriques d'aide concernant T-SQL, le contrôle chemin de fer en bas
de page permet de monter du nombre de niveaux voulu pour arriver à la
page centrale de l'aide de T-SQL.

Si j'ai bien compris, @@IDENTITY ne peut être utilisé que si on a cré é
un compteur ? On l'exploitera donc pour modifier un autre champ, qui ne
pourra pas être clef primaire, si on veut trier dessus il faudra le
préciser explicitement.
Avatar
Patrice
Bonjour,

Le compteur est géré de base par SQL Server via le mot clef IDENTITY
appliqué à la colonne concernée. Voir :
http://msdn.microsoft.com/fr-fr/library/ms186775.aspx

--
Patrice
Avatar
Gloops
Oui, c'est bien ce que j'en ai compris cet après-midi en lisant l'aide
sur le conseil de Michel.

D'ailleurs, je me rends compte que je n'avais pas prêté attention à la
remarque sur SQL-DMO Identity, qui, j'en ai l'impression, me réserve
encore un peu de lecture pour demain.
______________________________________
Patrice a écrit, le 12/12/2009 20:24 :
Bonjour,

Le compteur est géré de base par SQL Server via le mot clef IDENTIT Y
appliqué à la colonne concernée. Voir :
http://msdn.microsoft.com/fr-fr/library/ms186775.aspx

--
Patrice



1 2