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 :

Nom de colonne incorrect


Sujet :

Développement SQL Server

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Février 2009
    Messages : 98
    Points : 115
    Points
    115
    Par défaut Nom de colonne incorrect
    Bonjour à tous,
    J'ai peut être fait une erreur quelquepart. J'ai simplifié le code pour le reproduire a tous les coups. En decommentant une des lignes qui font appel à la colonne 'NumLigneInc', j'obtiens le message d'erreur msg 207, nom de colonne incorrect
    Si je mets une table normal (sans le #), le probleme est identique.

    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
     
    IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[TestErreur]') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
    	DROP PROCEDURE [dbo].[TestErreur]
    GO
    CREATE PROCEDURE [dbo].[TestErreur]
    AS
    	IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[TableTestSource]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
    		DROP TABLE [dbo].[TableTestSource]
     
    	CREATE TABLE [dbo].[TableTestSource](
    		[ID] uniqueidentifier ROWGUIDCOL  NOT NULL CONSTRAINT [DF_TableTestSource_ID]  DEFAULT (newid()),
    		[Nom] [nvarchar](50) NULL,
    		[NumLigne] [int] NULL,
    		CONSTRAINT [PK_ID] PRIMARY KEY CLUSTERED ([ID] ASC)WITH FILLFACTOR = 90 ON [PRIMARY],
    		) ON [PRIMARY]
     
    	INSERT INTO [dbo].[TableTestSource] (Nom, NumLigne) VALUES ('Ligne1','1')
    	INSERT INTO [dbo].[TableTestSource] (Nom, NumLigne) VALUES ('Ligne2','2')
    	INSERT INTO [dbo].[TableTestSource] (Nom, NumLigne) VALUES ('Ligne3','3')
     
    	SELECT TableTestSource.* INTO #TestLocal FROM TableTestSource WHERE 1=0
    	--On ajoute une colonne de numerotation automatique
    	ALTER TABLE #TestLocal ADD NumLigneInc bigint IDENTITY (0,1) NOT FOR REPLICATION
    	-- Histoire qu'il y ait quelques lignes
    	INSERT INTO #TestLocal (ID, Nom,NumLigne)
    		SELECT TOP 10 ID, Nom, NumLigne
    		FROM TableTestSource AS T
    -- Cette ligne provoque une erreur 'NumLigneInc" colonne inconnue
    --	UPDATE #TestLocal SET NumLigne=NumLigneInc + 1
     
    -- Cette ligne provoque une erreur 'NumLigneInc" colonne inconnue
    --	SELECT ID,Nom,NumLigne,NumLigneInc FROM #TestLocal
     
    -- Cette ligne ne provoque jamais d'erreur et 'NumLigneInc' est apparente
    	SELECT * FROM #TestLocal
     
    	DROP TABLE #TestLocal
    GO
    DECLARE @RC int
    EXECUTE @RC = [dbo].[TestErreur] 
    GO
    IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[TestErreur]') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
    	DROP PROCEDURE [dbo].[TestErreur]
    J'ai contourné le probleme en créant une table declaree en dur pour faire mon comptage, mais c'est un peu plus chaud pour la suite au niveau des requetes et des traitements.
    Merci si vous trouvez l'origine du probleme.

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Je viens de modifier quelque peu votre procédure :

    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
    CREATE PROCEDURE dbo.TestErreur
    AS
    BEGIN
    	IF EXISTS
    	(
    		SELECT *
    		FROM dbo.sysobjects
    		WHERE id = OBJECT_ID(N'dbo.TableTestSource')
    		AND OBJECTPROPERTY(id, N'IsUserTable') = 1
    	)
    	DROP TABLE dbo.TableTestSource
     
    	CREATE TABLE dbo.TableTestSource
    	(
    		ID UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL CONSTRAINT DF_TableTestSource_ID  DEFAULT (NEWID()),
    		Nom NVARCHAR(50) NULL,
    		NumLigne INT NULL,
    		CONSTRAINT PK_ID PRIMARY KEY (ID ) WITH FILLFACTOR = 90
    	)
     
    	INSERT INTO dbo.TableTestSource (Nom, NumLigne) VALUES ('Ligne1','1')
    	INSERT INTO dbo.TableTestSource (Nom, NumLigne) VALUES ('Ligne2','2')
    	INSERT INTO dbo.TableTestSource (Nom, NumLigne) VALUES ('Ligne3','3')
     
    	SELECT *
    	INTO #TestLocal
    	FROM TableTestSource
    	WHERE 1=0
     
    	--On ajoute une colonne de numerotation automatique
    	ALTER TABLE #TestLocal
    	ADD NumLigneInc BIGINT IDENTITY (0,1)
     
    	-- Histoire qu'il y ait quelques lignes
    	INSERT INTO #TestLocal
    	(
    		ID,
    		Nom,
    		NumLigne
    	)
    	SELECT TOP 10 ID, Nom, NumLigne
    	FROM TableTestSource AS T
     
    	-- Cette ligne provoque une erreur 'NumLigneInc" colonne inconnue
    	UPDATE #TestLocal
    	SET NumLigne = NumLigneInc + 1
     
    	-- Cette ligne provoque une erreur 'NumLigneInc" colonne inconnue
    	SELECT ID,
    			Nom,
    			NumLigne,
    			NumLigneInc
    	FROM #TestLocal
     
    	-- Cette ligne ne provoque jamais d'erreur et 'NumLigneInc' est apparente
    	SELECT *
    	FROM #TestLocal
     
    	DROP TABLE #TestLocal
    END
    GO
    et son exécution ne provoque pas d'erreur ...

    Vous devriez veiller :

    - à utiliser des noms d'objets tous avec des crochets dans toutes vos procédures stockées, ou tous sans crochets : la comparaison des requêtes dans le cache de plan se fait au motif près, donc si la même requête est soumise avec et sans crochets, on obtiendra deux plans d'exécution différents ...
    - toujours qualifier vos objets par le nom du schéma auquel ils appartiennent
    - ne pas utiliser * dans vos SELECT quand ils sont dans des modules SQL (procedure, trigger, fonction) : cela oblige le moteur de base de données à rechercher dans les tables de métadonnées les colonnes de votre ensemble, et l'empêche d'effectuer une compilation correcte puisqu'il ne connaît pas à l'avance les colonnes qui devront être retournées
    - ne pas mélanger des instructions DDL (CREATE, DROP) et DML (INSERT, UPDATE, DELETE, SELECT) dans la même procédure, pour les mêmes raisons.

    @++

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Février 2009
    Messages : 98
    Points : 115
    Points
    115
    Par défaut
    Merci pour la reponse,
    D'abord, rouge de honte, je n'ai pas dit que c'etait sous MSDE 2000 SP4 et que le test a été fait aussi sous EXPRESS 2005

    Cependant, le probleme ne semble pas venir de là puisque l'erreur est toujours vrai quand j'execute la procedure.
    Par contre, je suis entierement daccord avec les conseils prodigues. Il se trouve que mon exemple est juste la pour reproduire l'erreur.


    L'erreur ne se produit pas lorsqu'on fait l'ensemble des operations en ligne et non par une procedure. (Ajout de GO apres chaque ligne de commande, suppression de ce qui touche la definition de la procedure)

    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
     
    IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.TestErreur') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
    	DROP PROCEDURE dbo.TestErreur
    GO
    IF EXISTS
    (
    	SELECT *
    	FROM dbo.sysobjects
    	WHERE id = OBJECT_ID(N'dbo.TableTestSource')
    	AND OBJECTPROPERTY(id, N'IsUserTable') = 1
    )
    DROP TABLE dbo.TableTestSource
    GO 
    CREATE TABLE dbo.TableTestSource
    (
    	ID UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL CONSTRAINT DF_TableTestSource_ID  DEFAULT (NEWID()),
    	Nom NVARCHAR(50) NULL,
    	NumLigne INT NULL,
    	CONSTRAINT PK_ID PRIMARY KEY (ID ) WITH FILLFACTOR = 90
    )
    GO 
     
    INSERT INTO dbo.TableTestSource (Nom, NumLigne) VALUES ('Ligne1','1')
    INSERT INTO dbo.TableTestSource (Nom, NumLigne) VALUES ('Ligne2','2')
    INSERT INTO dbo.TableTestSource (Nom, NumLigne) VALUES ('Ligne3','3')
    GO
     
    -- CREATE PROCEDURE dbo.TestErreur
    --AS
    --BEGIN
     
    SELECT *
    INTO #TestLocal
    FROM TableTestSource
    WHERE 1=0
     
    GO
     
    --On ajoute une colonne de numerotation automatique
    ALTER TABLE #TestLocal
    ADD NumLigneInc BIGINT IDENTITY (0,1)
     
    GO
     
    -- Histoire qu'il y ait quelques lignes
    INSERT INTO #TestLocal
    (
    	ID,
    	Nom,
    	NumLigne
    )
    SELECT TOP 10 ID, Nom, NumLigne
    FROM TableTestSource AS T
     
    GO
     
    -- Cette ligne provoque pas l'erreur 'NumLigneInc" colonne inconnue
    UPDATE #TestLocal
    SET NumLigne = NumLigneInc + 1
     
    GO
     
    -- Cette ligne ne provoque pas l'erreur 'NumLigneInc" colonne inconnue
    SELECT ID,
    	Nom,
    	NumLigne,
    	NumLigneInc
    FROM #TestLocal
     
    GO
     
    -- Cette ligne ne provoque jamais d'erreur et 'NumLigneInc' est apparente
    SELECT *
    FROM #TestLocal
     
    GO 
     
    DROP TABLE #TestLocal
     
    GO
     
    -- END
     
    IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.TestErreur') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
    	DROP PROCEDURE dbo.TestErreur
    IF EXISTS
    (
    	SELECT *
    	FROM dbo.sysobjects
    	WHERE id = OBJECT_ID(N'dbo.TableTestSource')
    	AND OBJECTPROPERTY(id, N'IsUserTable') = 1
    )
    DROP TABLE dbo.TableTestSource
    GO

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 902
    Points : 53 143
    Points
    53 143
    Billets dans le blog
    6
    Par défaut
    L'instruction GO n'est pas du SQL, mais est utilisé par l'outil client (Enterprise Manager en v 2000) ou Management Studio (v 2005 et 2008). Elle sert de séparateur de batch. Retirez tous les GO dans la partie qui représente votre procédure et tout ira bien.
    Cependant vous faites appel à la table sysobjects qui n'est plus valable sous 2005. Evitez d'utiliser ce genre de table alors que vous pouvez utiliser les vues d'information de schéma qui sont la norme et sont valable pour toutes les versions.
    Dans votre cas, utilisez INFORMATION_SCHEMA.TABLES.

    A +

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Février 2009
    Messages : 98
    Points : 115
    Points
    115
    Par défaut
    En ce qui concerne le GO, je suis tout a fait d'accord avec vous. Si leur presence est ici, c'est pour que vous puissiez faire le test simplement avec une table d'essai, etc, etc... (mon premier post) Ou, dans mon dernier post, pour que vous fassiez le test sans la procedure stockee. Un copier coller dans l'analyseur de requete de 2000 ou dans Management Studio (2005 ou 2008). C'etait histoire de vous faire gagner du temps

    Ma procedure stockee de test NE comprend pas de GO. Elle est ceci:
    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
     
    CREATE PROCEDURE dbo.TestErreur
    AS
    BEGIN
     
    -- Creation de la table temporaire par 'modele' 
    SELECT * INTO #TestLocal FROM TableTestSource WHERE 1=0
     
    --On ajoute une colonne de numerotation automatique
    ALTER TABLE #TestLocal ADD NumLigneInc BIGINT IDENTITY (0,1)
     
    -- Histoire qu'il y ait quelques lignes
    INSERT INTO #TestLocal ( ID, Nom, NumLigne) SELECT TOP 10 ID, Nom, NumLigne FROM TableTestSource AS T
     
    -- Cette ligne provoque l'erreur 'NumLigneInc" colonne inconnue
    -- UPDATE #TestLocal SET NumLigne = NumLigneInc + 1
     
    -- Cette ligne provoque l'erreur 'NumLigneInc" colonne inconnue
    -- SELECT ID, Nom, NumLigne, NumLigneInc FROM #TestLocal
     
    -- Cette ligne ne provoque jamais d'erreur et 'NumLigneInc' est apparente
    SELECT * FROM #TestLocal
     
    DROP TABLE #TestLocal
     
    END
    En ce qui concerne sysobjects, je suis tout a fait d'accord avec vous, mais les vues INFORMATION_SCHEMA.xxxx ne me fournissent pas tout ce dont j'ai besoin dans mon application. Il est vrai que dans mon exemple, il aurai ete preferable de s'en servir ... force est d'habitude

    Bien evidement, dans 2005 j'avais corrigé l'acces à la table systeme ... sinon, nous avons une autre erreur qui n'est pas celle qui me preoccupe

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 448
    Points : 1 234
    Points
    1 234
    Par défaut
    Je vais peut-être dire une bétise, mais le problème pourrait venir du query optimizer.

    SQL Server, va essayer de définir un plan d'execution complet pour tes requêtes avant toute chose. Cela veut dire que le plan sera créer avant que tes DDL aient crée les colonnes auquel tu fais référence. Donc, le hic est qu'il cherche une colonne avant de la créer.

    Pour ton problème je te suggère...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    SELECT
     *
     , ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS NumLigneInc 
    INTO #TestLocal
    FROM TableTestSource
    WHERE 1=0
     
    SELECT * FROM #TestLocal
     
    DROP TABLE #TestLocal

Discussions similaires

  1. UNION :nom de colonne incorrect
    Par info3licen dans le forum Langage SQL
    Réponses: 3
    Dernier message: 02/06/2011, 23h44
  2. [JTable] les noms des colonnes de s'affichent pas
    Par macben dans le forum Composants
    Réponses: 6
    Dernier message: 25/04/2008, 11h03
  3. 'rowguidcol' : nom de colonne incorrect.
    Par zalalus dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 29/06/2007, 14h28
  4. Noms de colonne dans une colonne
    Par Digirom dans le forum Langage SQL
    Réponses: 14
    Dernier message: 23/04/2004, 11h51
  5. Mauvais noms de colonnes lors d'une requête
    Par nmathon dans le forum Bases de données
    Réponses: 2
    Dernier message: 09/04/2004, 07h27

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