918 votes

Fonction et procédure stockée dans SQL Server

J'ai appris les fonctions et les procédures stockées depuis un certain temps, mais je ne sais pas pourquoi et quand je dois utiliser une fonction ou une procédure stockée. Elles me paraissent identiques, peut-être parce que je suis un peu novice en la matière.

Quelqu'un peut-il me dire pourquoi ?

5 votes

1 votes

1 votes

776voto

MyItchyChin Points 6189

Les fonctions sont des valeurs calculées et ne peuvent pas effectuer des modifications permanentes de l'environnement de l'entreprise. SQL Server (c'est-à-dire qu'il n'y a pas de INSERT ou UPDATE autorisés).

Une fonction peut être utilisée en ligne dans SQL s'il retourne une valeur scalaire ou peut être joint s'il retourne un ensemble de résultats.

Un point à noter dans les commentaires, qui résument la réponse. Merci à @Sean K Anderson :

Les fonctions suivent la définition de l'informatique en ce sens qu'elles DOIVENT renvoyer une valeur et ne peuvent pas modifier les données qu'elles reçoivent en paramètre (les arguments). (les arguments). Les fonctions ne sont pas autorisées à modifier quoi que ce soit, doivent avoir au moins un paramètre, et elles doivent retourner une valeur. Stocké procs ne doivent pas avoir de paramètre, peuvent modifier les objets de la base de données, et ne doivent pas retourner une valeur.

16 votes

En fait, aucun DML n'est autorisé ?

193 votes

Les fonctions suivent la définition de l'informatique en ce sens qu'elles DOIVENT renvoyer une valeur et ne peuvent pas modifier les données qu'elles reçoivent en paramètre (les arguments). Les fonctions ne sont pas autorisées à modifier quoi que ce soit, doivent avoir au moins un paramètre et doivent retourner une valeur. Les procs stockés ne doivent pas avoir de paramètre, peuvent modifier les objets de la base de données et ne doivent pas retourner une valeur.

28 votes

En fait, vous pouvez avoir des instructions INSERT, UPDATE et DELETE dans une fonction, pour modifier les variables locales des tables.

714voto

Bhaumik Patel Points 2063

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

Procédure stockée (SP)

Fonction (UDF - User Defined)

SP peut renvoyer zéro, une ou plusieurs valeurs.

La fonction doit retourner une seule valeur (qui peut être un scalaire ou un tableau).

Nous pouvons utiliser la transaction dans la PS.

Nous ne pouvons pas utiliser la transaction dans UDF.

SP peut avoir un paramètre d'entrée/sortie.

Seul paramètre d'entrée.

Nous pouvons appeler la fonction à partir de SP.

On ne peut pas appeler SP depuis une fonction.

Nous ne pouvons pas utiliser la PS dans l'instruction SELECT/ WHERE/ HAVING.

Nous pouvons utiliser l'UDF dans l'instruction SELECT/ WHERE/ HAVING.

Nous pouvons utiliser la gestion des exceptions en utilisant le bloc Try-Catch dans SP.

Nous ne pouvons pas utiliser le bloc Try-Catch dans l'UDF.

23 votes

Les fonctions doivent retourner une valeur, ou un ensemble.

10 votes

Ce document est arrivé trois ans plus tard, mais il devrait être en tête parce qu'il est à la fois lisible et complet.

0 votes

SP peut utiliser à la fois des tables temporaires et des variables de table, alors que UDF ne peut utiliser que des variables de table. Les variables de table, quant à elles, ne peuvent pas utiliser d'index. UDF peut être appelé dans un CROSS APPLY, contrairement à SP.

196voto

Chris J Points 12904

Les fonctions et les procédures stockées ont des objectifs distincts. Bien que ce ne soit pas la meilleure analogie, 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 de lot.

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 (une fonction intégrée du serveur SQL telle 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 procs stockés sont utilisés pour lier des requêtes SQL dans une transaction et s'interfacer avec le monde extérieur. Les frameworks tels que ADO.NET, etc. ne peuvent pas appeler directement une fonction, mais ils peuvent appeler directement une proc stockée.

Les fonctions ont cependant un danger caché : elles peuvent être mal utilisées et causer des problèmes de performance plutôt désagréables : considérez cette requête :

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

Où MaFonction est déclarée comme :

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

   SELECT localValue 
      FROM dbo.localToNationalMapTable
      WHERE nationalValue = @someValue

   RETURN @retval
END

Ce qui se passe ici, c'est que la fonction MaFonction est appelée pour chaque ligne du tableau MaTable. Si MyTable comporte 1000 lignes, cela représente 1000 requêtes ad hoc supplémentaires dans 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, la fonction sera appelée pour chaque ligne renvoyée par le SELECT.

Il faut donc faire attention à l'écriture des fonctions. Si vous effectuez un SELECT à partir d'une table dans une fonction, vous devez vous demander s'il ne serait pas préférable d'utiliser un JOIN dans la proc stockée parente ou une autre construction SQL (telle que CASE ... WHEN ... ELSE ... END).

2 votes

Pouvez-vous préciser ce que vous entendez par "Les cadres tels que ADO.NET, etc. ne peuvent pas appeler une fonction directement" ? J'ai exécuté des fonctions avec des fournisseurs de données ADO.NET sans aucun problème.

25 votes

Vous devez appeler une fonction par l'intermédiaire d'une instruction SELECT - une fonction ne peut pas être appelée en tant que code indépendant - elle doit être appelée dans le cadre d'une instruction SQL plus large, même si cette instruction SQL n'est rien d'autre que SELECT * from dbo.MyTableValuedFunction() . Les sprocs, en revanche, peuvent être appelés directement avec ADO.NET en paramétrant SqlCommand.CommandType à CommandType.StoredProcedure .

66voto

Kumar Manish Points 1270

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 différée des noms.
  • Les procédures stockées sont généralement utilisées pour exécuter une 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 du Dynamic SQL.
  • 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 différée des noms.
  • Les fonctions définies par l'utilisateur sont généralement utilisées pour les calculs.
  • Les fonctions définies par l'utilisateur doivent retourner 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 fonctions définies par l'utilisateur peuvent avoir jusqu'à 1 023 paramètres d'entrée.
  • Les tables temporaires ne peuvent pas être utilisées dans les fonctions définies par l'utilisateur.
  • Les fonctions définies par l'utilisateur ne peuvent pas exécuter Dynamic SQL.
  • Les fonctions définies par l'utilisateur ne prennent pas en charge la gestion des erreurs. RAISEERROR OU @@ERROR ne sont pas autorisés dans les UDF.
  • Les fonctions non déterministes ne peuvent pas être utilisées dans les UDF. Par exemple, GETDATE() ne peuvent pas être utilisés dans les UDF.

2 votes

Pour citer @curiousBoy ci-dessous concernant une autre réponse non créditée (par @Ankit) (<-- vous voyez comment j'ai fait ça ? ;) ) : "Vous auriez dû donner la référence de la source. Ceci est tiré de ( blogs.msdn.microsoft.com/pradeepsvs/2014/10/08/ ). Veuillez respecter le travail des autres !"

7 votes

Ce blog a été écrit depuis le 8 octobre 2014 et cette réponse a été écrite depuis le 2 mai 2013 @Tom.

1 votes

@Code Rider : Ah, toutes mes excuses ! Je ne peux pas croire que je n'ai pas remarqué ça ! Donc, le blog vous a copié (ou quelqu'un d'autre l'a fait) sans crédit ?

58voto

Alex Martelli Points 330805

Écrivez une fonction définie par l'utilisateur lorsque vous souhaitez calculer et renvoyer une valeur à utiliser dans d'autres instructions SQL ; écrivez une procédure stockée lorsque vous souhaitez plutôt regrouper un ensemble éventuellement complexe d'instructions SQL. Il s'agit de deux cas d'utilisation assez différents, après tout !

19 votes

Il existe différents types de fonctions définies par l'utilisateur. Les fonctions scalaires ne renvoient que des valeurs ; les autres types retransmettent des ensembles de résultats.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X