sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo insertar los resultados de un procedimiento almacenado en una tabla temporal en SQL Server

En algunos casos con SQL Server, puede haber una instancia en la que desee tomar los datos resultantes de un procedimiento almacenado e insertarlos en una tabla temporal para usar en otra consulta. Determinar cómo realizar esta tarea puede ser algo difícil, por lo que describiremos brevemente un par de opciones, según sus necesidades específicas y la configuración de la base de datos.

Antes de examinar los métodos específicos, creemos un procedimiento de ejemplo. Si bien no es particularmente útil, creemos el BooksByPrimaryAuthor procedimiento, que acepta el @PrimaryAuthor parámetro y toma registros de nuestros books tabla donde @PrimaryAuthor partidos. La declaración de generación de procedimientos podría tener este aspecto:

CREATE PROC BooksByPrimaryAuthor
  @PrimaryAuthor nvarchar(100)
AS
BEGIN
  SELECT
    *
  FROM
    books
  WHERE
    primary_author = @PrimaryAuthor;
END
GO

Idealmente, lo que nos gustaría hacer es algo como esto, donde SELECT los datos resultantes de nuestro procedimiento e insértelos en una tabla temporal:

SELECT
  *
INTO
  #tmpSortedBooks
FROM
  EXEC BooksByPrimaryAuthor 'Tolkien'

El problema es que la sintaxis anterior es incorrecta y no funcionará . Necesitamos un nuevo método.

Uso de la instrucción OPENROWSET

Una posibilidad es usar el OPENROWSET instrucción, que le permite acceder a datos remotos desde una fuente OLE DB y se puede ejecutar directamente desde dentro de otra instrucción SQL. OPENROWSET es una conexión única y un método de recuperación de datos, por lo que no debe utilizarse para conexiones frecuentes (en ese caso, es preferible vincular servidores).

OPENROWSET puede ser el objetivo de cualquier INSERT , DELETE o UPDATE declaración, lo que lo hace ideal para nuestros propósitos de "ejecutar" nuestro procedimiento almacenado para nosotros y extraer esos datos a nuestra tabla temporal de espera.

Antes de usar OPENROWSET , puede ser necesario modificar algunas opciones de configuración, en concreto permitiendo accesos ad hoc. Esto se puede configurar usando las siguientes declaraciones:

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

Ahora podemos utilizar OPENROWSET , que tiene una sintaxis particular que debe cumplirse:

OPENROWSET(
  <PROVIDER_NAME>,
  <DATA_SOURCE>,
  <OPTIONS>
)

Por lo tanto, podemos ejecutar nuestro procedimiento almacenado a través de OPENROWSET y páselo a nuestra tabla temporal así:

SELECT
  *
INTO
  #tmpSortedBooks
FROM
  OPENROWSET(
    'SQLNCLI',
    'Server=(local)\SQL2008;Trusted_Connection=yes;',
    'EXEC BooksByPrimaryAuthor Tolkien'
)

Es posible que deba cambiar el PROVIDER_NAME y DATA_SOURCE valores para sus propios fines.

Usando una función definida por el usuario

Hay algunas desventajas en el OPENROWSET método, a saber, que requiere permisos/configuración ad hoc como vimos anteriormente, y también OPENROWSET solo puede devolver un único conjunto de resultados (si se proporcionan varios conjuntos, solo se devuelve el primer conjunto de resultados).

Por lo tanto, otro método para realizar esta tarea es reemplazar efectivamente el procedimiento almacenado con una función definida por el usuario.

De nuestro ejemplo, se vería así:

CREATE FUNCTION BooksByPrimaryAuthor
(
  @PrimaryAuthor nvarchar(100)
)
RETURNS TABLE
AS
RETURN
  SELECT
    *
  FROM
    books
  WHERE
    primary_author = @PrimaryAuthor;
GO

Esta función se puede usar más o menos de la misma manera que se desea anteriormente usando OPENROWSET :

SELECT
  *
INTO
  #tmpSortedBooks
FROM
  BooksByPrimaryAuthor('Tolkien')

En el caso de que realmente necesite un procedimiento almacenado, también puede envolver su función dentro de un procedimiento almacenado.