web-dev-qa-db-fra.com

Fonction vs procédure stockée dans SQL Server

Je connais les fonctions et les procédures stockées depuis un certain temps, mais je ne sais pas pourquoi ni quand utiliser une fonction ou une procédure stockée. Ils me semblent identiques, peut-être parce que je suis un débutant à ce sujet.

Quelqu'un peut-il me dire pourquoi?

778
Tarik

Les fonctions sont des valeurs calculées et ne peuvent pas effectuer de modifications environnementales permanentes dans SQL Server (c'est-à-dire qu'aucune instruction INSERT ou UPDATE n'est autorisée).

Une fonction peut être utilisée en ligne dans les instructions SQL si elle renvoie une valeur scalaire, ou peut être jointe si elle renvoie un ensemble de résultats.

n point à noter d'après les commentaires, qui résument la réponse. Merci à @Sean K Anderson:

Les fonctions suivent la définition de Computer-Sciency en ce sens qu'elles DOIVENT renvoyer une valeur et ne peuvent pas modifier les données qu'elles reçoivent en tant que paramètres (les arguments). Les fonctions ne sont pas autorisées à changer quoi que ce soit, doivent avoir au moins un paramètre et renvoyer une valeur. Les procédures stockées n'ont pas besoin de paramètre, peuvent modifier les objets de la base de données et ne doivent pas renvoyer de valeur.

671
MyItchyChin

La différence entre SP et UDF est indiquée ci-dessous:

+---------------------------------+----------------------------------------+
| Stored Procedure (SP)           | Function (UDF - User Defined           |
|                                 | Function)                              |
+---------------------------------+----------------------------------------+
| SP can return zero , single or  | Function must return a single value    |
| multiple values.                | (which may be a scalar or a table).    |
+---------------------------------+----------------------------------------+
| We can use transaction in SP.   | We can't use transaction in UDF.       |
+---------------------------------+----------------------------------------+
| SP can have input/output        | Only input parameter.                  |
| parameter.                      |                                        |
+---------------------------------+----------------------------------------+
| We can call function from SP.   | We can't call SP from function.        |
+---------------------------------+----------------------------------------+
| We can't use SP in SELECT/      | We can use UDF in SELECT/ WHERE/       |
| WHERE/ HAVING statement.        | HAVING statement.                      |
+---------------------------------+----------------------------------------+
| We can use exception handling   | We can't use Try-Catch block in UDF.   |
| using Try-Catch block in SP.    |                                        |
+---------------------------------+----------------------------------------+
578
Bhaumik Patel

Les fonctions et les procédures stockées ont des objectifs distincts. Bien que ce ne soit pas la meilleure des analogies, les fonctions peuvent être considérées littéralement comme n'importe quelle autre fonction que vous utiliseriez dans n'importe quel langage de programmation, mais les procédures stockées ressemblent davantage à des programmes individuels ou à un script batch.

Les fonctions ont normalement une sortie et éventuellement des entrées. La sortie peut ensuite être utilisée comme entrée d'une autre fonction (un serveur SQL intégré, tel que DATEDIFF, LEN, etc.) ou comme prédicat d'une requête SQL - par exemple, SELECT a, b, dbo.MyFunction(c) FROM table ou SELECT a, b, c FROM table WHERE a = dbo.MyFunc(c).

Les procédures stockées sont utilisées pour lier des requêtes SQL dans une transaction et pour s'interfacer avec le monde extérieur. Les frameworks tels que ADO.NET, etc. ne peuvent pas appeler une fonction directement, mais ils peuvent appeler directement un proc stocké.

Les fonctions présentent toutefois un danger caché: elles peuvent être mal utilisées et causer des problèmes de performances plutôt gênants: considérez cette requête:

SELECT * FROM dbo.MyTable WHERE col1 = dbo.MyFunction(col2)

Où MyFunction est déclaré comme:

CREATE FUNCTION MyFunction (@someValue INTEGER) RETURNS INTEGER
AS
BEGIN
   DECLARE @retval INTEGER

   SELECT localValue 
      FROM dbo.localToNationalMapTable
      WHERE nationalValue = @someValue

   RETURN @retval
END

Dans ce cas, la fonction MyFunction est appelée pour chaque ligne de la table MyTable. Si MyTable a 1000 lignes, cela signifie 1000 autres requêtes ad-hoc sur la base de données. De même, si la fonction est appelée lorsqu'elle est spécifiée dans la spécification de colonne, elle sera appelée pour chaque ligne renvoyée par SELECT.

Donc, vous devez être prudent en écrivant des fonctions. Si vous sélectionnez une table dans une fonction, vous devez vous demander si cela peut être mieux réalisé avec un JOIN dans le proc stocké parent ou une autre construction SQL (telle que CASE ... WHEN ... ELSE ... FIN).

186
Chris J

Ecrivez une fonction définie par l'utilisateur lorsque vous souhaitez calculer et renvoyer une valeur à utiliser dans d'autres instructions SQL. écrire une procédure stockée quand vous le souhaitez consiste à grouper un ensemble d'instructions SQL éventuellement complexes. Ce sont deux cas d'utilisation assez différents, après tout!

56
Alex Martelli

Différences entre les procédures stockées et les fonctions définies par l'utilisateur:

  • Les procédures stockées ne peuvent pas être utilisées dans les instructions Select.
  • Les procédures stockées prennent en charge la résolution de noms différée.
  • Les procédures stockées sont généralement utilisées pour exécuter la logique métier.
  • Les procédures stockées peuvent renvoyer n'importe quel type de données.
  • Les procédures stockées peuvent accepter un plus grand nombre de paramètres d'entrée que les fonctions définies par l'utilisateur. Les procédures stockées peuvent avoir jusqu'à 21 000 paramètres d'entrée.
  • Les procédures stockées peuvent exécuter le SQL dynamique.
  • Les procédures stockées prennent en charge la gestion des erreurs.
  • Les fonctions non déterministes peuvent être utilisées dans les procédures stockées.

  • Les fonctions définies par l'utilisateur peuvent être utilisées dans les instructions Select.
  • Les fonctions définies par l'utilisateur ne prennent pas en charge la résolution de nom différée.
  • Les fonctions définies par l'utilisateur sont généralement utilisées pour les calculs.
  • Les fonctions définies par l'utilisateur doivent renvoyer une valeur.
  • Les fonctions définies par l'utilisateur ne peuvent pas renvoyer d'images.
  • Les fonctions définies par l'utilisateur acceptent un plus petit nombre de paramètres d'entrée que les procédures stockées. Les fichiers UDF peuvent avoir jusqu'à 1 023 paramètres d'entrée.
  • Les tables temporaires ne peuvent pas être utilisées dans des fonctions définies par l'utilisateur.
  • Les fonctions définies par l'utilisateur ne peuvent pas exécuter le SQL dynamique.
  • Les fonctions définies par l'utilisateur ne prennent pas en charge la gestion des erreurs. RAISEERROR OR @@ERROR ne sont pas autorisés dans les fonctions définies par l'utilisateur.
  • Les fonctions non déterministes ne peuvent pas être utilisées dans les fonctions définies par l'utilisateur. Par exemple, GETDATE() ne peut pas être utilisé dans les fonctions définies par l'utilisateur.
56
              STORE PROCEDURE                 FUNCTION (USER DEFINED FUNCTION)    
 * Procedure can return 0, single or   | * Function can return only single value   
   multiple values.                    |
                                       |
 * Procedure can have input, output    | * Function  can have only input 
   parameters.                         |   parameters.         
                                       |
 * Procedure cannot be called from     | * Functions can be called from 
   function.                           |   procedure.
                                       |
 * Procedure allows select as well as  | * Function allows only select statement 
   DML statement in it.                |   in it.
                                       |
 * Exception can be handled by         | * Try-catch block cannot be used in a 
   try-catch block in a procedure.     |   function.
                                       |
 * We can go for transaction management| * We can't go for transaction 
   in procedure.                       |   management in function.
                                       |
 * Procedure cannot be utilized in a   | * Function can be embedded in a select 
   select statement                    |   statement.
                                       |
 * Procedure can affect the state      | * Function can not affect the state 
   of database means it can perform    |   of database means it can not    
   CRUD operation on database.         |   perform CRUD operation on 
                                       |   database. 
                                       |
 * Procedure can use temporary tables. | * Function can not use 
                                       |   temporary tables. 
                                       |
 * Procedure can alter the server      | * Function can not alter the  
   environment parameters.             |   environment parameters.
                                       |   
 * Procedure can use when we want      | * Function can use when we want
   instead is to group a possibly-     |   to compute and return a value
   complex set of SQL statements.      |   for use in other SQL 
                                       |   statements.
32
Aakash Singh

Différence fondamentale

La fonction doit renvoyer une valeur, mais dans la procédure stockée, elle est facultative (la procédure peut renvoyer des valeurs zéro ou n).

Les fonctions ne peuvent avoir que des paramètres d'entrée, alors que les procédures peuvent avoir des paramètres d'entrée/sortie.

La fonction prend un paramètre d’entrée, c’est obligatoire, mais la procédure stockée peut prendre de 0 à n paramètres d’entrée.

Les fonctions peuvent être appelées à partir de procédures alors que les procédures ne peuvent pas être appelées à partir de fonctions.

Différence d'avance

La procédure autorise les instructions SELECT ainsi que les instructions DML (INSERT/UPDATE/DELETE), alors que Function autorise uniquement les instructions SELECT.

Les procédures ne peuvent pas être utilisées dans une instruction SELECT, alors que Function peut être incorporé dans une instruction SELECT.

Les procédures stockées ne peuvent être utilisées dans les instructions SQL à aucun endroit de la section WHERE/HAVING/SELECT, alors que Function peut l'être.

Les fonctions qui renvoient des tables peuvent être traitées comme un autre ensemble de lignes. Ceci peut être utilisé dans des jointures avec d'autres tables.

Inline Function peut être considéré comme une vue prenant des paramètres et pouvant être utilisé dans les opérations JOIN et d'autres opérations Rowset.

Les exceptions peuvent être gérées par un bloc try-catch dans une procédure, alors que le bloc try-catch ne peut pas être utilisé dans une fonction.

Nous pouvons opter pour la gestion des transactions en procédure alors que nous ne pouvons pas aller en fonction.

source

22
Ankit

une fonction définie par l'utilisateur est un outil important disponible pour un programmeur de serveur SQL. Vous pouvez l'utiliser en ligne dans une instruction SQL comme si

SELECT a, lookupValue(b), c FROM customers 

lookupValue sera un fichier UDF. Ce type de fonctionnalité n'est pas possible lors de l'utilisation d'une procédure stockée. En même temps, vous ne pouvez pas faire certaines choses à l’intérieur d’une FDU. La chose fondamentale à retenir ici est que les FDU:

  • ne peut pas créer de changements permanents
  • ne peut pas changer les données

une procédure stockée peut faire ces choses.

Pour moi, l'utilisation en ligne d'un fichier UDF est l'utilisation la plus importante d'un fichier UDF.

19
OpenSource

Les procédures stockées sont utilisés comme scripts . Ils exécutent une série de commandes pour vous et vous pouvez planifier leur exécution à certains moments.

Fonctions sont utilisés comme méthodes. Vous transmettez quelque chose et vous obtenez un résultat. Devrait être petit et rapide - le fait à la volée.

13
Tigerjz32

Procédure stockée:

  • Est comme un programme miniature dans SQL Server.
  • Peut être aussi simple qu'une instruction select ou complexe qu'un long script qui ajoute, supprime, met à jour et/ou lit les données de plusieurs tables d'une base de données.
  • (Peut implémenter des boucles et des curseurs, qui vous permettent tous deux de travailler avec des résultats plus petits ou des opérations ligne par ligne sur des données.)
  • Devrait être appelé avec l'instruction EXEC ou EXECUTE.
  • Renvoie les variables de table, mais nous ne pouvons pas utiliser le paramètre OUT.
  • Prise en charge des transactions.

Une fonction:

  • Ne peut pas être utilisé pour mettre à jour, supprimer ou ajouter des enregistrements à la base de données.
  • Renvoie simplement une valeur unique ou une valeur de table.
  • Ne peut être utilisé que pour sélectionner des enregistrements. Cependant, il peut être appelé très facilement à partir de SQL standard, tel que:

    SELECT dbo.functionname('Parameter1')
    

    ou

    SELECT Name, dbo.Functionname('Parameter1') FROM sysObjects
    
  • Pour les opérations de sélection réutilisables simples, les fonctions peuvent simplifier le code. Méfiez-vous simplement d'utiliser les clauses JOIN dans vos fonctions. Si votre fonction a une clause JOIN et que vous l'appelez à partir d'une autre instruction select renvoyant plusieurs résultats, cet appel de fonction va JOIN ces tables ensemble pour each ligne renvoyée dans le résultat. ensemble. Ainsi, bien qu'ils puissent être utiles pour simplifier certaines logiques, ils peuvent également constituer un goulot d'étranglement en matière de performances s'ils ne sont pas utilisés correctement.

  • Renvoie les valeurs en utilisant le paramètre OUT.
  • Ne supporte pas les transactions.
8
JaiSankarN

Les fonctions de SQL Server, comme les curseurs, sont censées être votre dernière arme! Ils ont des problèmes de performances et, par conséquent, l'utilisation d'une fonction table doit être évitée autant que possible. Parler de performance, c'est parler d'une table avec plus de 1 000 000 enregistrements hébergés sur un serveur sur un matériel de classe moyenne; sinon, vous n'avez pas à vous soucier des conséquences sur les performances causées par les fonctions.

  1. Ne jamais utiliser une fonction pour renvoyer un jeu de résultats à un code externe (comme ADO.Net)
  2. Utilisez la combinaison vues/procédures stockées autant que possible. vous pouvez remédier aux futurs problèmes de performances de croissance en utilisant les suggestions que DTA (Database Tuning Adviser) vous donnerait (comme les vues indexées et les statistiques) - parfois!

pour plus de références, voir: http://databases.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.html =

6
Achilles

Pour décider quand utiliser ce que les points suivants pourraient aider-

  1. Les procédures stockées ne peuvent pas renvoyer une variable de table où function peut le faire.

  2. Vous pouvez utiliser des procédures stockées pour modifier les paramètres de l’environnement du serveur en utilisant des fonctions que vous ne pouvez pas.

à votre santé

6
Arnkrishn

Commencez avec des fonctions qui renvoient une seule valeur. La bonne chose est que vous pouvez mettre le code fréquemment utilisé dans une fonction et les renvoyer sous forme de colonne dans un jeu de résultats.

Ensuite, vous pouvez utiliser une fonction pour une liste de villes paramétrée. dbo.GetCitiesIn ("NY") Cela retourne une table qui peut être utilisée comme jointure.

C'est une façon d'organiser le code. Savoir quand quelque chose est réutilisable et quand c'est une perte de temps n'est acquis que par essais et erreurs et par l'expérience.

En outre, les fonctions sont une bonne idée dans SQL Server. Ils sont plus rapides et peuvent être assez puissants. Sélection en ligne et directe. Attention à ne pas abuser.

3
Andrew
  • Il est obligatoire pour Function de renvoyer une valeur alors que ce n'est pas pour la procédure stockée.
  • Sélectionnez les instructions acceptées uniquement dans UDF, alors que les instructions DML ne sont pas obligatoires.
  • La procédure stockée accepte toutes les instructions ainsi que les instructions DML.
  • UDF n'autorise que les entrées et non les sorties.
  • La procédure stockée autorise les entrées et les sorties.
  • Les blocs de capture ne peuvent pas être utilisés dans UDF mais peuvent être utilisés dans des procédures stockées.
  • Aucune transaction autorisée dans les fonctions de la fonction UDF mais dans les procédures stockées, elles sont autorisées.
  • Seules les variables de table peuvent être utilisées dans UDF et non les tables temporaires.
  • La procédure stockée autorise les variables de table et les tables temporaires.
  • UDF ne permet pas aux procédures stockées d'être appelées à partir de fonctions, alors que les procédures stockées permettent d'appeler des fonctions.
  • UDF est utilisé dans la clause de jointure alors que les procédures stockées ne peuvent pas être utilisées dans la clause de jointure.
  • Procédure stockée permettra toujours pour revenir à zéro. UDF, au contraire, a des valeurs qui doivent revenir à un point prédéterminé.
2
kombsh

Voici une raison pratique pour préférer les fonctions aux procédures stockées. Si vous avez une procédure stockée qui nécessite les résultats d'une autre procédure stockée, vous devez utiliser une instruction insert-exec. Cela signifie que vous devez créer une table temporaire et utiliser une instruction exec pour insérer les résultats de la procédure stockée dans la table temporaire. C'est désordonné. Un problème avec ceci est que insert-execs ne peut pas être imbriqué .

Si vous êtes bloqué par des procédures stockées qui appellent d'autres procédures stockées, vous pouvez vous heurter à cela. Si la procédure stockée imbriquée renvoie simplement un jeu de données, il peut être remplacé par une fonction table-value et vous n'obtiendrez plus cette erreur.

( c'est encore une autre raison de garder la logique applicative en dehors de la base de données )

2
user2023861
  • Les fonctions peuvent être utilisées dans une instruction select où les procédures ne peuvent pas.

  • La procédure stockée prend à la fois les paramètres d'entrée et de sortie, mais Functions prend uniquement les paramètres d'entrée.

  • Les fonctions ne peuvent pas renvoyer de valeurs de type text, ntext, image & timestamps, contrairement aux procédures.

  • Les fonctions peuvent être utilisées comme types de données définis par l'utilisateur dans create table, mais les procédures ne le peuvent pas.

*** Par exemple: -create table <tablename>(name varchar(10),salary getsal(name))

Getsal est une fonction définie par l'utilisateur qui renvoie un type de salaire. Lors de la création de la table, aucun stockage n'est alloué pour ce type de salaire. La fonction getsal n'est pas non plus exécutée. Cependant, lorsque nous récupérons certaines valeurs de cette table, la fonction getsal est exécutée et return Le type est renvoyé en tant que jeu de résultats.

1
Nick Kahn

Je réalise que la question est très ancienne, mais je ne vois aucun aspect crucial mentionné dans les réponses: s’inscrire dans le plan de requête.

Les fonctions peuvent être ...

  1. Scalaire:

    CREATE FUNCTION ... RETURNS scalar_type AS BEGIN ... END

  2. Valeur de table multi-instruction:

    CREATE FUNCTION ... RETURNS @r TABLE(...) AS BEGIN ... END

  3. Inline table-values:

    CREATE FUNCTION ... RETURNS TABLE AS RETURN SELECT ...

Le troisième type (valeur de table inline) est traité par l'optimiseur de requête essentiellement comme des vues (paramétrées), ce qui signifie que référencer la fonction à partir de votre requête est similaire à copier-coller du corps SQL de la fonction (sans copier-coller), ce qui conduit aux avantages suivants:

  • Le planificateur de requêtes peut optimiser l'exécution de la fonction inline de la même manière que toute autre sous-requête (par exemple, éliminer les colonnes inutilisées, réduire les prédicats, choisir différentes stratégies JOIN, etc.).
  • La combinaison de plusieurs fonctions en ligne ne nécessite pas de matérialiser le résultat de la première avant de l’alimenter à la suivante.

Ce qui précède peut entraîner des économies de performances significatives, notamment lorsque plusieurs niveaux de fonctions sont combinés.


REMARQUE: On dirait que SQL Server 2019 introduira également une forme de fonction scalaire en ligne .

1
Branko Dimitrijevic

Fonction définie par l'utilisateur.

  1. La fonction doit renvoyer une valeur.
  2. Autorise uniquement les instructions Select, cela ne nous permet pas d'utiliser les instructions DML.
  3. Cela permettra seulement les paramètres d'entrée, ne supporte pas les paramètres de sortie.
  4. Cela ne nous permettra pas d'utiliser des blocs try-catch.
  5. Les transactions ne sont pas autorisées dans les fonctions.
  6. Nous ne pouvons utiliser que des variables de table, cela ne permettra pas l'utilisation de tables temporaires.
  7. Les procédures stockées ne peuvent pas être appelées à partir d'une fonction.
  8. Les fonctions peuvent être appelées à partir d'une instruction select.
  9. Un fichier UDF peut être utilisé dans une clause de jointure en tant que jeu de résultats.

Procédure stockée

  1. La procédure stockée peut ou non renvoyer des valeurs.
  2. Peut avoir des instructions select ainsi que des instructions DML telles que insert, update, delete, etc.
  3. Il peut avoir à la fois des paramètres d'entrée et de sortie.
  4. Pour la gestion des exceptions, nous pouvons utiliser des blocs catch try.
  5. Peut utiliser des transactions dans les procédures stockées.
  6. Peut utiliser les deux variables de table ainsi que la table temporaire.
  7. Les procédures stockées peuvent appeler des fonctions.
  8. Les procédures ne peuvent pas être appelées à partir d'instructions Select/Where/Having et ainsi de suite. L'instruction Execute/Exec peut être utilisée pour appeler/exécuter une procédure stockée.
  9. Les procédures ne peuvent pas être utilisées dans la clause Join
0
Mahesh Waghmare