2008-10-07 40 views
83

Digamos que tengo que implementar una parte del código T-SQL que debe devolver una tabla como resultado. Puedo implementar una función con valores de tabla o un procedimiento almacenado que devuelve un conjunto de filas. ¿Qué debería usar?Funciones vs procedimientos almacenados

En resumen, lo que quiero saber es:

Cuáles son las principales diferencias entre las funciones y procedimientos almacenados? ¿Qué consideraciones debo tener en cuenta para usar una u otra?

+1

Esta parece ser la respuesta perfecta: http://stackoverflow.com/a/1179778/365188 –

Respuesta

48

Si es probable que desee combinar el resultado de este código con otras tablas, obviamente una función con valores de tabla le permitirá componer los resultados en una sola instrucción SELECT.

En general, hay una jerarquía (Ver < Función de TV < Stored Proc). Puede hacer más en cada uno, pero la capacidad de componer los resultados y que el optimizador se involucre realmente disminuye a medida que aumenta la funcionalidad.

Por lo tanto, utilice el que mínimamente le permita expresar el resultado deseado.

4

Personalmente utilizo funciones con valores de tabla cuando todo lo que devuelvo es una sola tabla sin efectos. Básicamente los trato como vistas parametrizadas.

Si necesito que vuelvan a aparecer varios conjuntos de registros o si hay valores actualizados en tablas, utilizo un procedimiento almacenado.

Mis 2 centavos

6

Si usted tiene una función que podría utilizarlo como parte de la instrucción SQL, por ejemplo

SELECT function_name(field1) FROM table 

No funciona de esta manera durante los procedimientos almacenados.

+1

Creo que estaba hablando de las funciones que devuelven valores de la tabla. – wcm

+1

Bueno, estoy hablando en general. Pero para mi caso específico ahora estoy actualmente entre un procedimiento almacenado o una función con valores de tabla. – Auron

48

Las funciones deben ser determinista, y no pueden ser utilizados para realizar cambios en la base de datos, mientras que los procedimientos almacenados le permiten hacer inserciones y actualizaciones, etc.

Usted debe limitar su uso de funciones, ya que suponen una enorme problema de escalabilidad para consultas grandes y complejas. Se convierten en una especie de "caja negra" para el optimizador de consultas, y verá enormes diferencias de rendimiento entre el uso de funciones y simplemente insertando el código en una consulta.

Pero son definitivamente útiles para retornos con valores de tabla en casos muy específicos.

Si necesita analizar una lista delimitada por comas, para simular el paso de una matriz a un procedimiento, una función puede convertir la lista en una tabla para usted. Esta es una práctica común con Sql Server 2005, ya que aún no podemos pasar las tablas a los procedimientos almacenados (podemos hacerlo en 2008).

+1

Pero puede enviar XML a un procedimiento almacenado: http://stackoverflow.com/questions/144550/sql-server-dynamic-where-clause – roosteronacid

+2

Incorrecto, la mayoría de las funciones del servidor SQL no son deterministas, como getdate en MS- Servidor SQL. Solo las funciones ODBC son funciones canónicas (= mucho más rápidas + indexables) ... Pero usted está muy correcto, uno debe limitar el uso de las funciones en las consultas tanto como sea posible por razones de rendimiento. –

1

Depende :) Si desea utilizar el resultado con valores de tabla en otro procedimiento, es mejor utilizar una función TableValued. Si los resultados son para un cliente, el proceso almacenado es generalmente la mejor manera de hacerlo.

41

From the docs:

Si un procedimiento almacenado cumple los siguientes criterios, que es un buen candidato para ser reescrito como una función de valor de tabla:

  • La lógica es expresable en una sola Instrucción SELECT, pero es un procedimiento almacenado, en lugar de una vista, solo por la necesidad de parámetros.

  • El procedimiento almacenado no realiza operaciones de actualización, excepto a las variables de la tabla.

  • No hay necesidad de sentencias EXECUTE dinámicas.

  • El procedimiento almacenado devuelve un conjunto de resultados.

  • El objetivo principal del procedimiento almacenado es generar resultados intermedios que se deben cargar en una tabla temporal, que luego se consulta en una instrucción SELECT.

1

Me perfromance prueba de ambos. Es probable que el enfoque sp o una tabla derivada sea significativamente más rápido que una función y, si es así, debería utilizarse ese enfoque. En general, evito las funciones porque pueden ser cerdas de rendimiento.

4

Como se mencionó anteriormente, las funciones son más legibles autodocumentado/componibles /, pero son menos eficiente en general, y pueden ser seriamente menos eficiente si se deja llevar con ellos en las combinaciones tales como

SELECT * 
FROM dbo.tvfVeryLargeResultset1(@myVar1) tvf1 
INNER JOIN dbo.tvfVeryLargeResultset1(@myVar2) tvf2 
    ON (tvf1.JoinId = tvf2.JoinId) 

menudo , solo tiene que aceptar la redundancia de código que un TVF podría eliminar (a un costo de rendimiento inaceptable).

Otro punto que aún no he mencionado es que no puede usar la temperatura de cambio de estado de la base de datos tablas dentro de un multi-statement tvf. El mecanismo más funcionalmente equivalente para una tabla temporal es el cambio no estatal, en la variable de la tabla de memoria, y para grandes conjuntos de datos, una tabla temporal probablemente será más eficiente que una variable de tabla. (Otras alternativas incluyen tablas dinámicas & expresiones de tabla común, pero en algún nivel de complejidad, dejan de ser una buena opción IMO.)

+0

¡Has hecho un buen punto! ¡Gracias! – Auron

5

Realicé algunas pruebas con un largo tiempo de lógica, con el mismo bit de código (una instrucción SELECT larga) que se ejecuta en una función con valores de tabla y un procedimiento almacenado, y un EXEC/SELECT directo, y cada uno se realiza de forma idéntica.

En mi opinión utilice siempre una función de valores de tabla en lugar de un procedimiento almacenado para devolver un conjunto de resultados, ya que hace la lógica mucho más fácil y legible en las consultas que posteriormente se unen a ellos, y le permite reutilizar la misma lógica. Para evitar el exceso de un impacto en el rendimiento, que a menudo utilizan los parámetros "opcionales" (es decir, se puede pasar NULL a ellos) para activar la función para devolver el conjunto de resultados a ser más rápido, por ejemplo:

CREATE FUNCTION dbo.getSitePermissions(@RegionID int, @optPersonID int, optSiteID int) 
AS 
RETURN 
    SELECT DISTINCT SiteID, PersonID 
    FROM dbo.SiteViewPermissions 
    WHERE (@optPersonID IS NULL OR @optPersonID = PersonID) 
    AND (@optSiteID IS NULL OR @optSiteID = SiteID) 
    AND @RegionID = RegionID 

De esta manera usted puede usar esta función para muchas situaciones diferentes y no da un gran golpe de rendimiento.Creo que esto es más eficiente que la filtración después:

SELECT * FROM dbo.getSitePermissions(@RegionID) WHERE SiteID = 1 

he utilizado esta técnica en varias funciones, a veces con una larga lista de parámetros "opcionales" de este tipo.

8
  1. procedimiento puede devolver cero o n valores mientras que la función puede devolver un valor que es obligatorio.

  2. Los procedimientos pueden tener parámetros de entrada/salida, mientras que las funciones solo pueden tener parámetros de entrada.

  3. El procedimiento permite seleccionar así como la declaración DML en él, mientras que la función solo permite seleccionar una instrucción en ella.

  4. Las funciones se pueden llamar desde el procedimiento, mientras que los procedimientos no pueden llamarse a desde la función.

  5. La excepción puede ser manejada por el bloque try-catch en un procedimiento mientras que el bloque try-catch no se puede usar en una función.

  6. Podemos ir a la gestión de transacciones en el procedimiento, mientras que no podemos entrar en funciones.

  7. Los procedimientos no se pueden utilizar en una instrucción select mientras que la función se puede incrustar en una instrucción select.

  8. UDF (función definida por el usuario) se puede utilizar en las sentencias SQL en cualquier lugar en la sección WHERE/HAVING/SELECT mientras que los procedimientos almacenados no pueden ser.

  9. Las UDF que devuelven tablas se pueden tratar como otro conjunto de filas. Esto se puede usar en JOIN s con otras tablas.

  10. Las UDF en línea se pueden considerar como vistas que toman parámetros y se pueden usar en JOIN sy otras operaciones del conjunto de filas.

10

Voy a escribir algunas diferencias interesantes entre los procedimientos almacenados y las funciones.

  • Podemos utilizar las funciones en las consultas de selección, pero no podemos usar almacenado procedimientos en las consultas de selección.
  • No podemos usar funciones no deterministas en Funciones pero podemos usar funciones no deterministas en procedimientos almacenados. Ahora pregunta surge, ¿cuál es la función no determinista .. Ans es: -

    Una función no determinista es que la función que devuelve diferentes salidas para los mismos valores de entrada en un momento diferente, al igual que getdate(). Siempre devuelve un valor diferente cada vez que se ejecuta.

    Excepción: -

    Las versiones anteriores de SQL Server anteriores a SQL 2000 no permiten utilizar la función getdate() en las funciones definidas por el usuario, pero la versión de 2005 y en adelante nos permite utilizar getdate() función dentro de una función definida por el usuario.

    Newid() es otro ejemplo de función no determinista pero no se puede usar en funciones definidas por el usuario, pero podemos usarlo en procedimientos almacenados.

  • podemos utilizar LMD (insertar, actualizar, eliminar) las declaraciones dentro de un procedimiento almacenado pero no podemos utilizar las sentencias DML en las funciones físicas en tablas o tablas permanentes. Si queremos realizar operaciones DML en las funciones , podemos hacerlo sobre variables de tabla que no estén en tablas permanentes.

  • No podemos usar el manejo de errores dentro de la función, pero podemos hacer el error manejo en procedimientos almacenados.

+0

¿Cómo es que las operaciones de DML son compatibles con las funciones de MySQL? –

Cuestiones relacionadas