Partager via


Procédures stockées étendues du Moteur de Base de Données de Programmation

S'applique à :SQL Server

Important

Cette fonctionnalité sera supprimée dans une prochaine version de SQL Server. Évitez d'utiliser cette fonctionnalité dans de nouveaux travaux de développement, et prévoyez de modifier les applications qui utilisent actuellement cette fonctionnalité. Utilisez plutôt l’intégration CLR .

Comment fonctionnent les procédures stockées étendues

Le processus par lequel fonctionne une procédure stockée étendue est le suivant :

  1. Lorsqu’un client exécute une procédure stockée étendue, la requête est transmise au format flux de données tabulaire (TDS) ou Simple Object Access Protocol (SOAP) de l’application client vers SQL Server.

  2. SQL Server recherche la DLL associée à la procédure de stockage étendue, et charge la DLL si elle n’est pas déjà chargée.

  3. SQL Server appelle la procédure de stockage étendue demandée (implémentée comme une fonction à l’intérieur de la DLL).

  4. La procédure stockée étendue transmet les ensembles de résultats et les paramètres de retour au serveur via l’API de procédure stockée étendue.

Par le passé, Open Data Services était utilisé pour écrire des applications serveurs, telles que des passerelles vers des environnements de bases de données non SQL Server. SQL Server ne prend pas en charge les parties obsolètes de l’API Open Data Services. La seule partie de l’API originale des services de données ouvertes encore prise en charge par SQL Server est celle des fonctions de procédure stockée étendue, si bien que l’API a été renommée API de procédure stockée étendue.

Avec l’émergence des requêtes distribuées et de l’intégration CLR, le besoin d’applications API à procédure stockée étendue a été largement remplacé.

Si vous avez déjà des applications passerelles, vous ne pouvez pas utiliser celles opends60.dll fournies avec SQL Server pour exécuter les applications. Les applications passerelles ne sont plus prises en charge.

Procédures stockées étendues vs. intégration CLR

L’intégration CLR offre une alternative plus robuste à l’écriture de logique côté serveur, difficile à exprimer ou impossible à écrire en Transact-SQL. Dans les versions antérieures de SQL Server, les procédures stockées étendues (XP) constituaient le seul mécanisme disponible pour les développeurs d’applications de bases de données afin d’écrire ce type de code.

Avec l’intégration CLR, la logique qui était auparavant écrite sous forme de procédures stockées est souvent mieux exprimée sous forme de fonctions à valeurs de table, qui permettent de interroger les résultats construits par la fonction en SELECT instructions en les intégrant dans la FROM clause.

Pour plus d’informations, voir aperçu de l’intégration CLR.

Caractéristiques d’exécution des procédures stockées étendues

L’exécution d’une procédure stockée étendue présente les caractéristiques suivantes :

  • La fonction de procédure stockée étendue est exécutée dans le contexte de sécurité de SQL Server.

  • La fonction de procédure stockée étendue s’exécute dans l’espace de processus de SQL Server.

  • Le thread associé à l’exécution de la procédure stockée étendue est le même que celui utilisé pour la connexion client.

Important

Avant d’ajouter des procédures stockées étendues au serveur et d’accorder des permissions d’exécution à d’autres utilisateurs, l’administrateur système doit examiner minutieusement chaque procédure stockée étendue pour s’assurer qu’elle ne contient pas de code nuisible ou malveillant.

Après le chargement de la DLL de procédure stockée étendue, la DLL reste chargée dans l’espace d’adressage du serveur jusqu’à ce que SQL Server soit arrêté ou que l’administrateur décharge explicitement la DLL en utilisant DBCC <DLL_name> (FREE).

La procédure stockée étendue peut être exécutée depuis Transact-SQL en tant que procédure stockée en utilisant l’instruction EXECUTE :

EXECUTE @retval = xp_extendedProcName @param1, @param2 OUTPUT;

Paramètres

@ Retval

Une valeur de retour.

@ param1

Paramètre d’entrée.

@ param2

Un paramètre d’entrée/sortie.

Caution

Les procédures stockées étendues offrent des améliorations de performance et étendent la fonctionnalité de SQL Server. Cependant, comme la DLL de procédure stockée étendue et SQL Server partagent le même espace d’adressage, une procédure problématique peut affecter négativement le fonctionnement de SQL Server. Bien que les exceptions apportées par la DLL de procédure stockée étendue soient gérées par SQL Server, il est possible d’endommager les zones de données SQL Server. Par mesure de sécurité, seuls les administrateurs système SQL Server peuvent ajouter des procédures stockées étendues à SQL Server. Ces procédures doivent être testées de manière approfondie avant d’être installées.

Envoyer des ensembles de résultats au serveur avec l’API Extended Stored Procedure

Lors de l’envoi d’un ensemble de résultats vers SQL Server, la procédure stockée étendue doit appeler l’API appropriée comme suit :

  • La srv_sendmsg fonction peut être appelée dans n’importe quel ordre avant ou après que toutes les lignes (le cas échéant) soient avec srv_sendrow. Tous les messages doivent être envoyés au client avant que l’état de complétion ne soit envoyé avec srv_senddone.

  • La srv_sendrow fonction est appelée une fois pour chaque ligne envoyée au client. Toutes les lignes doivent être envoyées au client avant que des messages, valeurs de statut ou statuts de complétion ne soient envoyés avec srv_sendmsg, l’argument srv_status de srv_pfield, ou srv_senddone.

  • Envoyer une ligne dont toutes les colonnes ne sont pas définies srv_describe fait apparaître un message d’erreur informationnel par l’application qui la renvoye FAIL au client. Dans ce cas, la ligne n’est pas envoyée.

Créer des procédures stockées étendues

Une procédure stockée étendue est une fonction C/C++ avec un prototype :

SRVRETCODE xp_extendedProcName ( SRVCV *) ;

L’utilisation du préfixe xp_ est optionnelle. Les noms de procédures stockées étendus sont sensibles à la casse lorsqu’ils sont référencés dans des instructions Transact-SQL, quel que soit la page de code ou l’ordre de tri installé sur le serveur. Lorsque vous construisez une DLL :

  • Si un point d’entrée est nécessaire, écrivez une DllMain fonction.

    Cette fonction est facultative. Si vous ne le fournissez pas en code source, le compilateur lie sa propre version, qui ne fait que renvoyer TRUE. Si vous fournissez une DllMain fonction, le système d’exploitation appelle cette fonction lorsqu’un thread ou un processus s’attache ou se détache de la DLL.

  • Toutes les fonctions appelées en dehors de la DLL (toutes les Efunctions de procédures stockées étendues) doivent être exportées.

    Vous pouvez exporter une fonction en listant son nom dans la EXPORTS section d’un .def fichier, ou vous pouvez préfixer le nom de la fonction dans le code source par __declspec(dllexport), une extension du compilateur Microsoft (__declspec() commence par deux sous-traits).

Ces fichiers sont nécessaires pour créer une DLL de procédure stockée étendue.

Fichier Descriptif
srv.h Fichier d’en-tête de l’API Extended Stored Procedure
opends60.lib Bibliothèque d’importation pour opends60.dll

Pour créer une DLL de procédure stockée étendue, créez un projet de type Dynamic Link Library. Pour plus d’informations sur la création d’une DLL, consultez la documentation de l’environnement de développement.

Toutes les DLL de procédures stockées étendues doivent implémenter et exporter la fonction suivante :

__declspec(dllexport) ULONG __GetXpVersion()
{
   return ODS_VERSION;
}

__declspec(dllexport) est une extension de compilateur spécifique à Microsoft. Si votre compilateur ne supporte pas cette directive, vous devez exporter cette fonction dans votre DEF fichier sous la EXPORTS section.

Lorsque SQL Server est lancé avec le drapeau -T260 de trace ou si un utilisateur disposant de privilèges administrateur système s’exécute DBCC TRACEON (260), et si la DLL de procédure stockée étendue ne prend pas en charge __GetXpVersion(), le message d’avertissement suivant est imprimé dans le journal des erreurs (__GetXpVersion() commence par deux sous-traitants).

Error 8131: Extended stored procedure DLL '%' does not export __GetXpVersion().

Si la DLL de procédure stockée étendue exporte __GetXpVersion(), mais que la version retournée par la fonction est inférieure à la version requise par le serveur, un message d’avertissement indiquant la version retournée par la fonction et celle attendue par le serveur est imprimé dans le journal d’erreurs. Si vous recevez ce message, vous retournez une valeur incorrecte de __GetXpVersion(), ou vous compilez avec une version plus ancienne de srv.h.

Note

SetErrorMode, une fonction Win32, ne devrait pas être appelée dans les procédures stockées étendues.

Les procédures stockées longues et prolongées doivent appeler srv_got_attention périodiquement, afin que la procédure puisse s’arrêter si la connexion est coupée ou si le lot est interrompu.

Pour déboguer une DLL de procédure stockée étendue, copiez-la dans le répertoire SQL Server \Binn . Pour spécifier l’exécutable de la session de débogage, saisissez le chemin et le nom du fichier exécutable SQL Server (par exemple, C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\Binn\sqlservr.exe). Pour des informations sur sqlservr les arguments, voir application sqlservr.

Ajouter une procédure stockée étendue à SQL Server

Une DLL contenant des fonctions de procédure stockée étendues agit comme une extension de SQL Server. Pour installer la DLL, copiez le fichier dans un répertoire, comme celui qui contient les fichiers DLL standards de SQL Server (C:\Program Files\Microsoft SQL Server\MSSQL16.0.<x>\MSSQL\Binn par défaut).

Après la copie de la DLL de procédure stockée étendue sur le serveur, un administrateur système SQL Server doit enregistrer chaque fonction de procédure stockée étendue dans la DLL sur SQL Server. Cela se fait à l’aide de la sp_addextendedproc procédure de stockage système.

Important

L’administrateur système doit examiner attentivement une procédure stockée étendue pour s’assurer qu’elle ne contient pas de code nuisible ou malveillant avant de l’ajouter au serveur et d’accorder des permissions d’exécution à d’autres utilisateurs. Validez toutes les entrées utilisateur. Ne concaténez pas les entrées utilisateur avant de les valider. N'exécutez jamais une commande élaborée à partir d'une entrée utilisateur non validée.

Le premier paramètre de sp_addextendedproc spécifie le nom de la fonction, et le second paramètre spécifie le nom de la DLL dans laquelle réside cette fonction. Vous devez spécifier le chemin complet de la DLL.

Note

Les DLL existantes qui n’étaient pas enregistrées avec un chemin complet ne fonctionnent plus après la mise à jour vers SQL Server 2005 (9.x) ou une version ultérieure. Pour corriger le problème, utilisez sp_dropextendedproc le désenregistrement de la DLL, puis réenregistrez-la en sp_addextendedproc, spécifiant le chemin complet.

Le nom de la fonction spécifiée dans sp_addextendedproc doit être exactement le même, y compris le cas, que le nom de la fonction dans la DLL. Par exemple, cette commande enregistre une fonction xp_hello, située dans une dll nommée xp_hello.dll, comme une procédure stockée étendue de SQL Server :

sp_addextendedproc 'xp_hello', 'c:\Program Files\Microsoft SQL Server\MSSQL13.0.MSSQLSERVER\MSSQL\Binn\xp_hello.dll';

Si le nom de la fonction spécifiée dans sp_addextendedproc ne correspond pas exactement à celui de la DLL, le nouveau nom est enregistré dans SQL Server, mais le nom n’est pas utilisable. Par exemple, bien qu’il xp_Hello soit enregistré comme une procédure stockée étendue de SQL Server située dans xp_hello.dll, SQL Server ne peut pas trouver la fonction dans la DLL si vous utilisez xp_Hello pour appeler la fonction ultérieurement.

-- Register the function (xp_hello) with an initial upper case
sp_addextendedproc 'xp_Hello', 'c:\xp_hello.dll';

-- Use the newly registered name to call the function
DECLARE @txt VARCHAR(33);
EXEC xp_Hello @txt OUTPUT;

Voici le message d’erreur :

Server: Msg 17750, Level 16, State 1, Procedure xp_Hello, Line 1
Could not load the DLL xp_hello.dll, or one of the DLLs it references. Reason: 127(The specified procedure could not be found.).

Si le nom de la fonction spécifiée dans sp_addextendedproc correspond exactement à celui de la DLL, et que la collation de l’instance SQL Server est insensible à la majuscule, l’utilisateur peut appeler la procédure stockée étendue en utilisant n’importe quelle combinaison de lettres minuscules et majuscules du nom.

-- Register the function (xp_hello)
sp_addextendedproc 'xp_hello', 'c:\xp_hello.dll';

-- The following example succeeds in calling xp_hello
DECLARE @txt VARCHAR(33);
EXEC xp_Hello @txt OUTPUT;

DECLARE @txt VARCHAR(33);
EXEC xp_HelLO @txt OUTPUT;

DECLARE @txt VARCHAR(33);
EXEC xp_HELLO @txt OUTPUT;

Lorsque la collation de l’instance SQL Server est sensible aux casse, SQL Server ne peut pas appeler la procédure stockée étendue si la procédure est appelée avec un autre cas. Cela est vrai même s’il était enregistré avec exactement le même nom et la même collation que la fonction dans la DLL.

-- Register the function (xp_hello)
sp_addextendedproc 'xp_hello', 'c:\xp_hello.dll';

-- The following example results in an error
DECLARE @txt VARCHAR(33);
EXEC xp_HELLO @txt OUTPUT;

Voici le message d’erreur :

Server: Msg 2812, Level 16, State 62, Line 1

Vous n’avez pas besoin d’arrêter et de redémarrer SQL Server.

Requête des procédures stockées étendues installées dans SQL Server

Un utilisateur authentifié par SQL Server peut afficher les procédures stockées étendues définies actuellement et le nom du DLL auquel chacune appartient en exécutant la sp_helpextendedproc procédure système. Par exemple, l’exemple suivant renvoie la DLL à laquelle xp_hello appartient :

sp_helpextendedproc 'xp_hello';

Si sp_helpextendedproc est exécuté sans spécifier une procédure stockée étendue, toutes les procédures stockées étendues et leurs DLL sont affichées.

Supprimer une procédure stockée étendue de SQL Server

Pour supprimer chaque fonction de procédure stockée étendue dans une DLL de procédure stockée étendue définie par l’utilisateur, un administrateur système SQL Server doit exécuter la sp_dropextendedproc procédure stockée système, en spécifiant le nom de la fonction et celui de la DLL dans laquelle réside cette fonction. Par exemple, cette commande supprime la fonction xp_hello, située dans une DLL nommée xp_hello.dll, depuis SQL Server :

sp_dropextendedproc 'xp_hello';

sp_dropextendedproc ne perd pas les procédures stockées étendues du système. Au lieu de cela, l’administrateur système doit refuser EXECUTE l’autorisation de la procédure stockée étendue au rôle public .

Décharger une DLL de procédure stockée étendue

SQL Server charge une DLL de procédure stockée étendue dès qu’un appel est effectué vers l’une des fonctions de la DLL. La DLL reste chargée jusqu’à ce que le serveur soit éteint ou jusqu’à ce que l’administrateur système utilise l’instruction DBCC pour la décharger. Par exemple, cette commande décharge le xp_hello.dll, permettant à l’administrateur système de copier une version plus récente de ce fichier dans le répertoire sans éteindre le serveur :

DBCC xp_hello(FREE);