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 :

Fonction scalaire avec paramètre variable en mode compatibilité 80


Sujet :

Développement SQL Server

  1. #1
    Membre régulier
    Inscrit en
    Juillet 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 207
    Points : 85
    Points
    85
    Par défaut Fonction scalaire avec paramètre variable en mode compatibilité 80
    Bonjour à tous,

    J'essaie de faire une requête qui affiche dans un champ le retour d'une fonction de type scalaire qui a comme paramètre le champ d'une autre table.

    Or ma base de données est en mode compatibilité SQL Server 2000 (80) et j'ai cette erreur :
    If it is intended as a parameter to a table-valued function or to the CHANGETABLE function, ensure that your database compatibility mode is set to 90

    et cette requête fonctionne très bien en mode compatibilité 90.

    Voici ma requête en très simplifié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT  TABLE1.ID,(select VALEUR from FCT_SCAL(CHAMP1)) as VALEUR
    from TABLE1
    FCT_SCAL() est la fonction scalaire.
    CHAMP1 est le champ de la tables TABLE1 qui donne le paramètre à la fonction.

    Auriez vous une solution, hormis bien-sûr de modifier le mode compatibilité de la base de données ?

    Merci d'avance
    David

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 735
    Points
    52 735
    Billets dans le blog
    5
    Par défaut
    Non !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  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
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Vous parlez de fonction scalaire, mais vous l'utilisez (mal) comme une fonction table.

    N'est pas ceci que vous voulez faire : ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT  TABLE1.ID, dbo.FCT_SCAL(CHAMP1) as VALEUR
    from TABLE1

  4. #4
    Membre régulier
    Inscrit en
    Juillet 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 207
    Points : 85
    Points
    85
    Par défaut
    Bonjour,

    Merci de vos réponses

    En effet j'avais commencé par l'utiliser comme ça mais j'ai cette erreur :

    Cannot find either column "dbo" or the user-defined function or aggregate "dbo.FCT_SCAL", or the name is ambiguous.

    Exemple même en effectuant simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT dbo.FCT_SCAL(6) as VALEUR;
    J'ai l'erreur ci-dessus

    Alors que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT VALEUR FROM dbo.FCT_SCAL(6);
    fonctionne

  5. #5
    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 : 42
    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,

    C'est donc une fonction de table : elle retourne une table, et pas une (seule) valeur.
    Sous SQL Server 2000, il faut donc faire en sorte que la fonction de table retourne TABLE1.ID, par exemple en passant en paramètre sa valeur, pour pouvoir ensuite spécifier une jointure dessus.
    Dès SQL Server 2005, on peut utiliser l'opérateur APPLY.

    Quoi qu'il en soit, ces deux versions ne sont plus supportées par Microsoft. Il faudrait donc considérer un upgrade vers une version plus récente

    @++

  6. #6
    Membre régulier
    Inscrit en
    Juillet 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 207
    Points : 85
    Points
    85
    Par défaut
    Merci de ta réponse. Je vais chercher de ce côté là alors.
    Il s'agit de sql server 2008 R2 mais qui est en mode compatibilité 2000 pour des raisons d'applications ne pouvant pas évoluer.

    Bon week-end !

  7. #7
    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 : 42
    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
    OK. Donc deux problèmes :

    • Si vous passez un jour à SQL Server 2014, le mode de compatibilité 80 ne sera plus disponible
    • L'opérateur APPLY et de nombreuses autres fonctionnalités ne seront pas utilisables


    @++

  8. #8
    Membre régulier
    Inscrit en
    Juillet 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 207
    Points : 85
    Points
    85
    Par défaut
    Oui je comprend bien pour le problème d'évolution de version.

    Sinon j'ai essayé de créer une fonction table que l'on appellera FCT_TAB(id) qui en lui passant un paramètre identifiant retourne une table contenant 3 champs : id, champ1, champ2
    Si je fais une requête select simple sur cette table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM FCT_TAB(36)
    aucun problème cela me retourne bien les 3 champs.

    Mais si j'essaye de faire une jointure sur cette fonction table avec une autre table en passant le paramètre de l'identifiant ça ne fonctionne pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT TAB1.id, TAB1.champ1, TAB1.champ2, TAB2.champ1
    FROM FCT_TAB(TAB2.id) as TAB1, TABLE_2 as TAB2
    WHERE TAB1.id = TAB2.id
    Je ne sais pas comment utiliser cette fonction table.

  9. #9
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 735
    Points
    52 735
    Billets dans le blog
    5
    Par défaut
    Vous ne pouvez pas le faire en restant dans cette version.

    Il faut passer en version 2005 au minimum.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  10. #10
    Membre régulier
    Inscrit en
    Juillet 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 207
    Points : 85
    Points
    85
    Par défaut
    Pourtant Elsuket dit :
    "Sous SQL Server 2000, il faut donc faire en sorte que la fonction de table retourne TABLE1.ID, par exemple en passant en paramètre sa valeur, pour pouvoir ensuite spécifier une jointure dessus."

  11. #11
    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 : 42
    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,

    si j'essaye de faire une jointure sur cette fonction table avec une autre table en passant le paramètre de l'identifiant ça ne fonctionne pas.
    Quel résultat obtenez-vous ? S'il y a une erreur, pouvez-vous nous en donner le libellé complet SVP ?

    @++

  12. #12
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 735
    Points
    52 735
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par davelop Voir le message
    Pourtant Elsuket dit :
    "Sous SQL Server 2000, il faut donc faire en sorte que la fonction de table retourne TABLE1.ID, par exemple en passant en paramètre sa valeur, pour pouvoir ensuite spécifier une jointure dessus."
    Ce qui nécessite l'utilisation de l'opérateur APPLY qui n'est apparu qu'avec la version 2005.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  13. #13
    Membre régulier
    Inscrit en
    Juillet 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 207
    Points : 85
    Points
    85
    Par défaut
    Bonjour,

    Alors elsuket cela m'indique "Incorrect syntax near 'TAB2.id'."

    En tout cas merci pour vos réponses.

    Bonne journée

  14. #14
    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 : 42
    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
    SQLPro a raison, je prends donc allègrement mon zéro pointé; désolé davelop.
    Sans l'opérateur APPLY, on ne peut effectivement réaliser une jointure sur une fonction de table que si celle-ci ne prend pas en paramètre les valeurs de colonnes d'une autre table participant à la requête : d'où d'ailleurs son intérêt

    Il ne reste donc que la fonction scalaire : il faut donc transformer la fonction dbo.FCT_SCAL(), qui est actuellement de TABLE, en une fonction scalaire : ceci vous permettra alors d'utiliser l'exemple d'aieeeuuuuu.
    Ceci implique que la fonction de table actuelle ne retourne qu'une seule ligne et une seule colonne.

    @++

  15. #15
    Membre régulier
    Inscrit en
    Juillet 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 207
    Points : 85
    Points
    85
    Par défaut
    Pas de souci. C'est déjà bien sympa de prendre le temps de répondre pour aider.

    La fonction scalaire c'est ce que j'avais au début (voir post #4) mais je n'arrive pas à l'utiliser comme une fonction scalaire qui pourtant doit bien retourner qu'une seule valeur (un entier)

  16. #16
    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 : 42
    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
    Pouvez-vous nous donner le code de la fonction SVP ?

    @++

  17. #17
    Membre régulier
    Inscrit en
    Juillet 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 207
    Points : 85
    Points
    85
    Par défaut
    Hello,

    Oui le voici :

    C'est une fonction qui calcule une note retard d'un labo en se plaçant à une année et un mois.
    A cette date (mois/année) la dernière note enregistrée perd 10 points par mois de retard.



    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
    ALTER FUNCTION [dbo].[cinqs_fct_note_labo]
    (	
    	-- Add the parameters for the function here
    	@annee int, @mois int, @labo int
    )
    RETURNS int 
    AS
    BEGIN
    DECLARE @note_retard int;
     
     
    	-- Add the SELECT statement with parameter references here
    select top 1 @note_retard = case  WHEN note-10*((@annee*100+@mois)-(annee_eval*100+mois_eval))<0 then 0 else note-10*((@annee*100+@mois)-(annee_eval*100+mois_eval)) End
    from cinqs_evaluation
    where id_labo = @labo and (annee_eval*100 + mois_eval) <= (@annee*100 + @mois)
    order by annee_eval desc, mois_eval desc
     
     
    RETURN @note_retard
    END

  18. #18
    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
    bonjour,

    Alors vous devriez pouvoir faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT [dbo].[cinqs_fct_note_labo](2016,10,1)
    Par ailleurs, pourquoi faire tous ces calculs à la main ? (qui en plus je pense seront faux pour les périodes à cheval sur plusieurs années)
    Un simple DATEDIFF(MONTH,...) devrait suffire pour calculer le nombre de mois entre les deux dates.

Discussions similaires

  1. Fonction scalaire avec paramètre de type DateTime2
    Par FRinguette dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 10/10/2014, 00h16
  2. [PHP-JS] Fonction js avec paramètre PHP
    Par pcayrol dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 28/06/2007, 10h59
  3. Requête avec paramètres variables
    Par dahu17 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 30/05/2007, 10h38
  4. Réponses: 11
    Dernier message: 30/03/2006, 15h39
  5. Réponses: 4
    Dernier message: 09/02/2006, 16h22

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