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 :

Table "dynamique" dans une fonction table


Sujet :

Développement SQL Server

  1. #1
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2014
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Août 2014
    Messages : 257
    Points : 395
    Points
    395
    Par défaut Table "dynamique" dans une fonction table
    Bonjour

    Alors je sais pas si ce que je vais demander est possible ou même si c'est beau (je n'en suis pas totalement sûr) mais je vais essayer de m'expliquer.
    Dans ma base de donnée, il y a une table qui recense l'historique des requêtes insert/update/delete dans cette même base. Cette table contient l'id du type de requete, la date de la requete, la table ciblé par la requete, l'id de l'utilisateur l'ayant effectuée ainsi que l'id cible dans la table. Par exemple, je modifier un centre ayant pour ID 2, j'aurais donc deux dans le champs id_cible de ma requête.
    J'ai fait une première fonction me permettant de renvoyer plus précisément ma table historique requête, tout va bien, maintenant, le soucis arrive. J'avais dans l'idée de faire une fonction montrant le détail de la ligne infectée par la requête faite par l'utilisateur. Le soucis est le suivant :
    Je n'ai, logiquement, pas le même nombre de colonnes dans ma table centre et dans ma table utilisateurs (par exemple), du coup, je ne peux pas savoir à l'avance combien de colonnes mettre dans ma fonction de type table, ni quel nom mettre à ces colonnes. Je voudrais donc savoir si il existait une méthode dynamique pour faire cela ou non

    En espérant avoir été clair...

    Merci

    Ps : Si cela peut aider, j'avais eu dans l'idée de faire :

    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
     
    create function DetailHistorique(@IdHistorique int)
    returns @DetailHistorique table
    (
    	idHistorique int identity(1,1)
    )
    as
    	begin
     
    		declare @Table varchar(50);
    		declare @NomIdTable varchar(50);
    		declare @IdCible int;
     
    		set @Table = (select TableCible from HistoriqueRequete where Id_Historique = @IdHistorique);
    		set @NomIdTable = (select Nom_id_table from Tables_bdd where Nom_table = @Table);
    		set @IdCible = (select Id_cible_requete from HistoriqueRequete where id_Historique = @IdHistorique);
     
     
    		select * into @DetailHistorique from @Table where @NomIdTable = @IdCible;
     
    	return
    	end
    go

  2. #2
    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
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par JeanYvette Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * into @DetailHistorique from @Table
    Ceci ne fonctionnera pas. Il faudrait passer par du SQL dynamique, ce qui n'est pas autorisé dans les fonctions.

    quel est le but de tout cela ? comment compter vous utiliser cette fonction par la suite ?

  3. #3
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2014
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Août 2014
    Messages : 257
    Points : 395
    Points
    395
    Par défaut
    Bonjour,

    Le but est le suivant, un administrateur se connecte sur le site (en asp.net) et voit la liste des historiques requêtes, présentant la date, type, table, idcible, et utilisateurs qui a fait la requête. Une fois sur cette page, il peut faire diverses recherches, ect... Tout ça, c'est fait
    Maintenant ce que je veux c'est que notre administrateur, une fois qu'il a sélectionné la ligne qu'il veut "inspecter", il puisse en voir les détails, et ce que j'entend par détail, c'est la ligne dans la table sélectionnée. Donc par exemple si on a modifier notre centre 2, l'administrateur verra la ligne de l'enregistrement 2 de notre table centre

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Et pourquoi n'utilisez vous pas des trigers en ce cas ?

    Autre solution (que j'ai déjà rencontrée chez un client, mais qui n'a pas ma préférence) : avoir une table mouchard contenant un longvarchar qui stocke la concaténation des différentes colonnes de votre table d'origine avec une ligne pour la valeur avant et une autre pour la valeur après mise à jour. En cas d'insert, seule la valeur après existe, en cas de delete, seule la valeur avant.

  5. #5
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2014
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Août 2014
    Messages : 257
    Points : 395
    Points
    395
    Par défaut
    La solution vue chez votre client peut passer je pense, il faut que je vois
    De base, je voulais passer par une fonction car c'est ce qu'on me demande, tout les create/update/delete doivent passer par une procédure stockée, et les select (notre cas) par des fonctions

  6. #6
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut
    Bonjour,
    Pourquoi ne pas utiliser une procédure stockée pour un SELECT ? J'en avais fait une pour récupérer les libellé d'une table de telle sort que ce soit paramétrable

    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
     
    IF OBJECT_ID (N'dbo.MaPS', N'P') IS NOT NULL
    	DROP PROCEDURE MaPS
    GO
     
    CREATE PROCEDURE MaPS
    	@nvcTableName SYSNAME
    ,	@nvcLanguage typSmartCode = NULL
    AS
    BEGIN
    	SET @nvcTableName = ISNULL(@nvcTableName, N'');
    	SET @nvcLanguage = IIF(ISNULL(@nvcLanguage, N'') = N'', N'FR', @nvcLanguage);
     
    	IF OBJECT_ID (N'dbo.' + @nvcTableName, N'U') IS NOT NULL
    		EXEC (N'SELECT		T.nvcLabel
    				  FROM	' + @nvcTableName + N' S
    							INNER JOIN	tblTranslation T ON T.CdeLabel = S.CdeLabel
    							INNER JOIN	tblLanguage L ON T.CdeLanguage = L.LID
    				 WHERE	L.chrCodeISO2 = ''' + @nvcLanguage + N'''
    				 ORDER
    					BY	T.nvcLabel')
    END;
    GO
    Ca marche nickel

    Du coup je te proposerais bien ce 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
     
    IF OBJECT_ID (N'dbo.MaPS', N'P') IS NOT NULL
    	DROP PROCEDURE MaPS
    GO
     
    CREATE PROCEDURE MaPS
    	@nvcTableName SYSNAME
    ,	@nvcLanguage typSmartCode = NULL
    AS
    BEGIN
    	SET @nvcTableName = ISNULL(@nvcTableName, N'');
    	SET @nvcLanguage = IIF(ISNULL(@nvcLanguage, N'') = N'', N'FR', @nvcLanguage);
     
    	IF OBJECT_ID (N'dbo.' + @nvcTableName, N'U') IS NOT NULL
    	BEGIN
    		INSERT INTO MaTableHistorique
    			VALUES (...);
    		EXEC (N'SELECT	T.nvcLabel
    				  FROM	' + @nvcTableName + N' S
    							INNER JOIN	tblTranslation T ON T.CdeLabel = S.CdeLabel
    							INNER JOIN	tblLanguage L ON T.CdeLanguage = L.LID
    				 WHERE	L.chrCodeISO2 = ''' + @nvcLanguage + N'''
    				 ORDER
    					BY	T.nvcLabel')
    	END;
    END;
    GO

  7. #7
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2014
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Août 2014
    Messages : 257
    Points : 395
    Points
    395
    Par défaut
    Bonjour,

    Désolé du temps de réponse, et merci pour le code. Par contre je sais pas si je suis stupide ou quoi, mais je comprends pas vraiment le code que tu m'as donné

  8. #8
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut
    Arfff, c'est vrai qu'avec un peu de commentaires c'est toujours mieux

    Pour mon cas, c'était assurer de récupérer les listes déroulantes d'une table dans la bonne langue.

    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
    -- Si la procédure existe alors la supprimer
    IF OBJECT_ID (N'dbo.MaPS', N'P') IS NOT NULL
    	DROP PROCEDURE MaPS
    GO
     
    -- Créer la procédure stockée
    CREATE PROCEDURE MaPS
    	@nvcTableName SYSNAME
    ,	@nvcLanguage typSmartCode = NULL
    AS
    BEGIN
    	-- Controler que la table est bien renseigné, sinon mettre une chaine de caractères vide
    	SET @nvcTableName = ISNULL(@nvcTableName, N'');
    	-- Si la langue n'est pas renseignée alors prendre la langue par dé
    	SET @nvcLanguage = IIF(ISNULL(@nvcLanguage, N'') = N'', N'FR', @nvcLanguage);
     
    	-- Si la table existe alors récupérer la liste des labels de la table (cette ligne évite l'injection de code SQL par le nom de la table)
    	IF OBJECT_ID (N'dbo.' + @nvcTableName, N'U') IS NOT NULL
    		EXEC (N'SELECT		T.nvcLabel
    			  FROM	' + @nvcTableName + N' S
    					INNER JOIN	tblTranslation T ON T.CdeLabel = S.CdeLabel
    					INNER JOIN	tblLanguage L ON T.CdeLanguage = L.LID
    			 WHERE	L.chrCodeISO2 = ''' + @nvcLanguage + N'''
    			 ORDER BY	T.nvcLabel')
    END;
    GO
    Pour adapter à ton cas :
    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
    -- Si la procédure existe alors la supprimer
    IF OBJECT_ID (N'dbo.MaPS', N'P') IS NOT NULL
    	DROP PROCEDURE MaPS
    GO
     
    -- Créer la procédure stockée
    CREATE PROCEDURE MaPS
    	@nvcTableName SYSNAME
    AS
    BEGIN
    	-- Si la table existe alors faire ce dont tu as besoin (cette ligne évite l'injection de code SQL par le nom de la table)
    	IF OBJECT_ID (N'dbo.' + ISNULL(@nvcTableName, N''), N'U') IS NOT NULL
    	BEGIN
    		-- Historiser la demande de sélection
    		INSERT INTO MaTableHistorique
    			VALUES (...);
    		-- Faire la sélection demandée de façon dynamique
    		EXEC (N'SELECT	MesChamps
    			  FROM	' + @nvcTableName + N'
    			 WHERE	MaConditionCaractère = ''Toto''
    			   AND	MaConditionNumérique = 5')
     /* Attention à bien mettre 2 fois la simple quote pour les chaines de caractères*/
    	END;
    END;
    GO

  9. #9
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2014
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Août 2014
    Messages : 257
    Points : 395
    Points
    395
    Par défaut
    En effet, je test ça dès cet après midi je te dirais ce que ça aura donné
    Merci

  10. #10
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut
    Alors ça a donné quoi ???

  11. #11
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut
    Youhou, il y a quelqu'un ??? Tu dis essayer et revenir me dire si c'est bon mais je ne vois personne revenir

Discussions similaires

  1. Réponses: 7
    Dernier message: 18/06/2012, 11h30
  2. [MySQL] Nom de table dynamique dans une jointure
    Par CsJoe dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 05/08/2009, 14h13
  3. Recherche dans table MySQL dans une fonction js
    Par dodo91 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 20/05/2009, 11h00
  4. table temporaire dans une fonction
    Par jsteffe dans le forum PostgreSQL
    Réponses: 7
    Dernier message: 21/12/2007, 14h26
  5. Impossible de créer une table temporaire dans une fonction
    Par bossun dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 05/10/2007, 10h03

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