Programación Motor de base de datos procedimientos almacenados extendidos

Se aplica a: SQL Server

Importante

Esta característica se quitará en una versión futura de SQL Server. Evite utilizar esta característica en nuevos trabajos de desarrollo y tenga previsto modificar las aplicaciones que actualmente la utilizan. Use la integración clR en su lugar.

Funcionamiento de los procedimientos almacenados extendidos

El procedimiento almacenado extendido funciona del siguiente modo:

  1. Cuando un cliente ejecuta un procedimiento almacenado extendido, la solicitud se transmite en el flujo de datos tabular (TDS) o el formato protocolo simple de acceso a objetos (SOAP) de la aplicación cliente a SQL Server.

  2. SQL Server busca el archivo DLL asociado al procedimiento almacenado extendido y carga el archivo DLL si aún no está cargado.

  3. SQL Server llama al procedimiento almacenado extendido solicitado (implementado como una función dentro del archivo DLL).

  4. El procedimiento almacenado extendido pasa conjuntos de resultados y devuelve parámetros de retorno al servidor mediante la API Procedimiento almacenado extendido.

En el pasado, los Servicios abiertos de datos se usaban para escribir las aplicaciones de servidor, como las puertas de enlace a entornos de bases de datos que no son de SQL Server. SQL Server no admite las partes obsoletas de open Data Services API. La única parte de la API de Open Data Services original que todavía es compatible con SQL Server son las funciones de procedimiento almacenado extendido, por lo que se cambió el nombre de la API de procedimiento almacenado extendido.

Con la aparición de consultas distribuidas y la integración clR, la necesidad de aplicaciones de API de procedimiento almacenado extendido se ha reemplazado en gran medida.

Si tiene aplicaciones de puerta de enlace existentes, no puede usar el opends60.dll que se incluye con SQL Server para ejecutar las aplicaciones. Ya no se admiten las aplicaciones de puerta de enlace.

Procedimientos almacenados extendidos frente a integración clR

La integración clR proporciona una alternativa más sólida a la escritura de lógica del lado servidor que era difícil de expresar o imposible escribir en Transact-SQL. En versiones anteriores de SQL Server, los procedimientos almacenados extendidos (XP) proporcionaban el único mecanismo que estaba disponible para que los desarrolladores de aplicaciones de base de datos escriban dicho código.

Con la integración clR, la lógica que se usa para escribirse en forma de procedimientos almacenados a menudo se expresa mejor como funciones con valores de tabla, lo que permite consultar los resultados construidos por la función en SELECT instrucciones mediante la inserción de ellos en la FROM cláusula .

Para obtener más información, consulte Introducción a la integración de CLR.

Características de ejecución de procedimientos almacenados extendidos

La ejecución de un procedimiento almacenado extendido tiene estas características:

  • La función de procedimiento almacenado extendido se ejecuta en el contexto de seguridad de SQL Server.

  • La función de procedimiento almacenado extendido se ejecuta en el espacio de procesos de SQL Server.

  • El subproceso asociado a la ejecución del procedimiento almacenado extendido es el mismo que se utiliza para la conexión de cliente.

Importante

Antes de agregar procedimientos almacenados extendidos al servidor y conceder permisos de ejecución a otros usuarios, el administrador del sistema debe revisar exhaustivamente cada procedimiento almacenado extendido para asegurarse de que no contiene código dañino o malintencionado.

Una vez cargado el archivo DLL del procedimiento almacenado extendido, el archivo DLL permanece cargado en el espacio de direcciones del servidor hasta que SQL Server se detiene o el administrador descarga explícitamente el archivo DLL mediante DBCC <DLL_name> (FREE).

El procedimiento almacenado extendido se puede ejecutar desde Transact-SQL como un procedimiento almacenado mediante la EXECUTE instrucción :

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

Parámetros

@ retval

Valor devuelto.

@ param1

Parámetro de entrada.

@ param2

Parámetro de entrada/salida.

Precaución

Los procedimientos almacenados extendidos ofrecen mejoras de rendimiento y amplían la funcionalidad de SQL Server. Sin embargo, dado que el archivo DLL del procedimiento almacenado extendido y SQL Server comparten el mismo espacio de direcciones, un procedimiento de problema puede afectar negativamente al funcionamiento de SQL Server. Aunque SQL Server controla las excepciones producidas por el archivo DLL de procedimiento almacenado extendido, es posible dañar las áreas de datos de SQL Server. Como precaución de seguridad, solo los administradores del sistema de SQL Server pueden agregar procedimientos almacenados extendidos a SQL Server. Antes de instalar estos procedimientos, se deberían probar con detenimiento.

Envío de conjuntos de resultados al servidor con la API de procedimiento almacenado extendido

Al enviar un conjunto de resultados a SQL Server, el procedimiento almacenado extendido debe llamar a la API adecuada de la siguiente manera:

  • Es posible que se llame a la srv_sendmsg función en cualquier orden antes o después de todas las filas (si las hay) con srv_sendrow. Todos los mensajes deben enviarse al cliente antes de enviar el estado de finalización con srv_senddone.

  • Se llama a la srv_sendrow función una vez para cada fila enviada al cliente. Todas las filas deben enviarse al cliente antes de que se envíen mensajes, valores de estado o estados de finalización con srv_sendmsg, el srv_status argumento de o .srv_senddonesrv_pfield

  • El envío de una fila que no tiene todas sus columnas definidas con srv_describe hace que la aplicación genere un mensaje de error informativo y vuelva FAIL al cliente. En este caso, no se envía la fila.

Creación de procedimientos almacenados extendidos

Un procedimiento almacenado extendido es una función de C/C++ con un prototipo:

SRVRETCODE xp_extendedProcName ( SRVPROC *);

El uso del prefijo xp_ es opcional. Los nombres de procedimientos almacenados extendidos distinguen mayúsculas de minúsculas cuando se hace referencia en instrucciones Transact-SQL, independientemente del criterio de ordenación o página de códigos instalado en el servidor. Cuando genere un archivo DLL:

  • Si es necesario un punto de entrada, escriba una DllMain función.

    Esta función es opcional. Si no lo proporciona en el código fuente, el compilador vincula su propia versión, que no hace nada más que devolver TRUE. Si proporciona una DllMain función, el sistema operativo llama a esta función cuando un subproceso o proceso se adjunta o se desasocia del archivo DLL.

  • Deben exportarse todas las funciones a las que se llama desde el exterior del archivo DLL (todas las funciones Efunction de procedimiento almacenado extendido).

    Puede exportar una función enumerando su nombre en la EXPORTS sección de un .def archivo, o bien puede prefijar el nombre de la función en el código fuente con __declspec(dllexport), una extensión del compilador de Microsoft (__declspec() comienza con dos caracteres de subrayado).

Estos archivos son necesarios para crear un archivo DLL de procedimientos almacenados extendidos.

Archivo Descripción
srv.h Archivo de encabezado de la API Procedimiento almacenado extendido
opends60.lib Importar biblioteca para opends60.dll

Para crear un archivo DLL de procedimientos almacenados extendidos, cree un proyecto de tipo biblioteca de vínculos dinámicos. Para obtener más información sobre la forma de crear un archivo DLL, vea la documentación del entorno de desarrollo.

Todos los archivos DLL de procedimiento almacenado extendido deben implementar y exportar la siguiente función:

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

__declspec(dllexport) es una extensión del compilador específica de Microsoft. Si el compilador no admite esta directiva, debe exportar esta función en el archivo en DEF la EXPORTS sección .

Cuando SQL Server se inicia con la marca -T260 de seguimiento o si un usuario con privilegios de administrador del sistema ejecuta DBCC TRACEON (260), y si el archivo DLL de procedimiento almacenado extendido no admite __GetXpVersion(), el siguiente mensaje de advertencia se imprime en el registro de errores (__GetXpVersion() comienza con dos caracteres de subrayado).

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

Si el archivo DLL del procedimiento almacenado extendido exporta __GetXpVersion(), pero la versión devuelta por la función es menor que la versión requerida por el servidor, se imprime un mensaje de advertencia que indica la versión devuelta por la función y la versión esperada por el servidor en el registro de errores. Si recibe este mensaje, va a devolver un valor incorrecto de __GetXpVersion()o está compilando con una versión anterior de srv.h.

Nota:

SetErrorMode, una función Win32, no se debe llamar a en procedimientos almacenados extendidos.

Los procedimientos almacenados extendidos de larga duración deben llamar srv_got_attention periódicamente, de modo que el procedimiento pueda finalizarse si se elimina la conexión o se anula el lote.

Para depurar un archivo DLL de procedimiento almacenado extendido, cópielo en el directorio de SQL Server \Binn . Para especificar el archivo ejecutable para la sesión de depuración, escriba la ruta de acceso y el nombre de archivo del archivo ejecutable de SQL Server (por ejemplo, C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\Binn\sqlservr.exe). Para obtener información sobre sqlservr los argumentos, vea sqlservr Application.

Agregar un procedimiento almacenado extendido a SQL Server

Un archivo DLL que contiene funciones de procedimiento almacenado extendido actúa como una extensión para SQL Server. Para instalar el archivo DLL, copie el archivo en un directorio, como el que contiene los archivos DLL estándar de SQL Server (C:\Program Files\Microsoft SQL Server\MSSQL16.0.<x>\MSSQL\Binn de forma predeterminada).

Después de copiar el archivo DLL del procedimiento almacenado extendido en el servidor, un administrador del sistema de SQL Server debe registrarse en SQL Server cada función de procedimiento almacenado extendido en el archivo DLL. Esto se hace mediante el procedimiento almacenado del sp_addextendedproc sistema.

Importante

El administrador del sistema debe revisar exhaustivamente un procedimiento almacenado extendido para asegurarse de que no contiene código dañino o malintencionado antes de agregarlo al servidor y conceder permisos de ejecución a otros usuarios. Valide todos los datos proporcionados por el usuario. No concatene la entrada del usuario antes de validarla. No ejecute nunca un comando creado a partir de una entrada de usuario no validada.

El primer parámetro de sp_addextendedproc especifica el nombre de la función y el segundo parámetro especifica el nombre del archivo DLL en el que reside esa función. Debe especificar la ruta de acceso completa del archivo DLL.

Nota:

Los archivos DLL existentes que no se registraron con una ruta de acceso completa no funcionan después de actualizar a SQL Server 2005 (9.x) o una versión posterior. Para corregir el problema, use sp_dropextendedproc para anular el registro del archivo DLL y, a continuación, vuelva a registrarlo con sp_addextendedproc, la especificación de la ruta de acceso completa.

El nombre de la función especificada en sp_addextendedproc debe ser exactamente el mismo que el nombre de la función del archivo DLL, incluidas las mayúsculas y minúsculas. Por ejemplo, este comando registra una función xp_hello, ubicada en un archivo DLL denominado xp_hello.dll, como un procedimiento almacenado extendido de SQL Server:

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

Si el nombre de la función especificada en sp_addextendedproc no coincide exactamente con el nombre de la función en el archivo DLL, el nuevo nombre se registra en SQL Server, pero el nombre no se puede usar. Por ejemplo, aunque xp_Hello se registra como un procedimiento almacenado extendido de SQL Server ubicado en xp_hello.dll, SQL Server no puede encontrar la función en el archivo DLL si usa xp_Hello para llamar a la función más adelante.

-- 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;

Este es el mensaje de error:

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 el nombre de la función especificada en sp_addextendedproc coincide exactamente con el nombre de la función en el archivo DLL y la intercalación de la instancia de SQL Server no distingue mayúsculas de minúsculas, el usuario puede llamar al procedimiento almacenado extendido mediante cualquier combinación de letras minúsculas y mayúsculas del nombre.

-- 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;

Cuando la intercalación de la instancia de SQL Server distingue mayúsculas de minúsculas, SQL Server no puede llamar al procedimiento almacenado extendido si se llama al procedimiento con un caso diferente. Esto es cierto incluso si se registró exactamente con el mismo nombre y intercalación que la función en el archivo 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;

Este es el mensaje de error:

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

No es necesario detener y reiniciar SQL Server.

Consulta de procedimientos almacenados extendidos instalados en SQL Server

Un usuario autenticado de SQL Server puede mostrar los procedimientos almacenados extendidos definidos actualmente y el nombre del archivo DLL al que pertenece cada uno ejecutando el procedimiento del sp_helpextendedproc sistema. Por ejemplo, en el ejemplo siguiente se devuelve el archivo DLL al que xp_hello pertenece:

sp_helpextendedproc 'xp_hello';

Si sp_helpextendedproc se ejecuta sin especificar un procedimiento almacenado extendido, se muestran todos los procedimientos almacenados extendidos y sus archivos DLL.

Eliminación de un procedimiento almacenado extendido de SQL Server

Para quitar cada función de procedimiento almacenado extendido en un archivo DLL de procedimiento almacenado extendido definido por el usuario, un administrador del sistema de SQL Server debe ejecutar el procedimiento almacenado del sp_dropextendedproc sistema, especificando el nombre de la función y el nombre del archivo DLL en el que reside esa función. Por ejemplo, este comando quita la función xp_hello, ubicada en un archivo DLL denominado xp_hello.dll, de SQL Server:

sp_dropextendedproc 'xp_hello';

sp_dropextendedproc no quita los procedimientos almacenados extendidos del sistema. En su lugar, el administrador del sistema debe denegar EXECUTE el permiso en el procedimiento almacenado extendido al rol público .

Descargar un archivo DLL de procedimiento almacenado extendido

SQL Server carga un archivo DLL de procedimiento almacenado extendido en cuanto se realiza una llamada a una de las funciones del archivo DLL. El archivo DLL permanece cargado hasta que el servidor se cierra o hasta que el administrador del sistema usa la DBCC instrucción para descargarlo. Por ejemplo, este comando descarga , xp_hello.dlllo que permite al administrador del sistema copiar una versión más reciente de este archivo en el directorio sin apagar el servidor:

DBCC xp_hello(FREE);