SQL Server: ¿dónde está "sys.functions"?

104

SQL Server 2005 tiene excelentes vistas sys.XXX en el catálogo del sistema que utilizo con frecuencia.

Lo que me sorprende es esto: ¿por qué hay una vista "sys.procedures" para ver información sobre sus procedimientos almacenados, pero no hay una vista "sys.functions" para ver lo mismo para sus funciones almacenadas?

¿Nadie usa funciones almacenadas? ¡Los encuentro muy útiles para, por ejemplo, columnas calculadas y demás!

¿Hay una razón específica por la que faltan las funciones del sistema, o es simplemente algo que no se consideró lo suficientemente importante como para incluirlo en las vistas del catálogo del sistema? ¿Está disponible en SQL Server 2008?

Saludos, Marc

marc_s
fuente
La respuesta proporcionada por TimC (respondida el 22 de enero a las 14:06) es preferible al uso de la tabla del sistema sysobjects más antigua, porque tiene una columna LAST_ALjected en INFORMATION_SCHEMA.ROUTINES que es similar a la columna modified_date que existe en sys.tables, sys.views, sys.procedures, etc. Sin embargo, si está utilizando la vista del sistema sys.objects más actualizada, tiene modified_date como en esas tablas. Mis $ 0.02. Saludos,
-Matthew
1
@JuniorMayhe: ok, aquí está el comentario de sugerencia de Connect que ingresé, ¡ve y vota! :-)
marc_s
1
Creo que @marc_s tiene un buen punto: mucha gente no puede entender por qué no existe sys.functions. Tienes sys.foreign_keysy no sys.primary_keys. De todos modos, les pido que usen el canal abierto de Microsoft para proponer y sugerir nuevas funciones para las versiones futuras de SQL Server en connect.microsoft.com/SQLServer/Feedback Ya he agregado un comentario sobre sys.functions en connect.microsoft.com/ SQLServer / feedback / details / 1127920
Junior Mayhé

Respuestas:

117

Encuentro que las UDF son muy útiles y las uso todo el tiempo.

No estoy seguro de cuál es la razón fundamental de Microsoft para no incluir un equivalente de sys.functions en SQL Server 2005 (o SQL Server 2008, por lo que puedo decir), pero es bastante fácil desarrollar el suyo:

CREATE VIEW my_sys_functions_equivalent
AS
SELECT *
FROM sys.objects
WHERE type IN ('FN', 'IF', 'TF')  -- scalar, inline table-valued, table-valued
LukeH
fuente
7
Esto también debe incluir los tipos de función CLR: 'AF', 'FS' y 'FT'. Consulte la descripción de la columna "tipo" de sys.objects aquí: msdn.microsoft.com/en-us/library/ms190324.aspx
Triynko
4
"AF" no se considera una "función" en términos de los metadatos del objeto de SQL Server, aunque significa AGGREGATE_FUNCTION. Es más claro que un agregado es un tipo de objeto diferente de otras funciones definidas por el usuario cuando se considera que crea un nuevo agregado usando CREAR AGREGADO en lugar de CREAR FUNCIÓN. Los tipos de objeto 'FN', 'IF', 'TF', 'FS' y 'FT' son los cinco tipos de funciones por lo que SSMS (a través de SMO) genera cuando se escribe el código SI EXISTS ... DROP FUNCTION.
Orlando Colamatteo
37

Otra forma de enumerar las funciones es hacer uso de las vistas INFORMATION_SCHEMA.

SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'FUNCTION'

Según el sitio web de Microsoft, "las vistas de esquema de información proporcionan una vista interna, independiente de la tabla del sistema, de los metadatos de SQL Server. Las vistas de esquema de información permiten que las aplicaciones funcionen correctamente, aunque se han realizado cambios significativos en las tablas del sistema subyacente". En otras palabras, las tablas del sistema subyacentes pueden cambiar a medida que se actualiza SQL, pero las vistas deberían seguir siendo las mismas.

Tim C
fuente
Sí, gracias, también conozco el INFORMATION_SCHEMA, pero como usuario de mucho tiempo, sys.xxxx todavía es más fácil, ¡gracias por el recordatorio!
marc_s
4
INFORMATION_SCHEMA sería genial, pero no incluye el cuerpo completo de procedimientos más grandes, lo que lo hace menos que inútil si está buscando en el cuerpo. No es lo que no sabes lo que te meterá en problemas, pero lo que sabes no es tan ...
jmoreno
3
Las vistas Information_Schema están expresamente documentadas como no confiables para algunas cosas. por ejemplo, "No use las vistas INFORMATION_SCHEMA para determinar el esquema de un objeto. La única forma confiable de encontrar el esquema de un objeto es consultar la vista del catálogo sys.objects". de msdn.microsoft.com/en-us/library/ ms188757.aspx
David Eison
Me gusta esta respuesta, porque la INFORMATION_SCHEMAconsulta devuelve resultados muy interesantes como IS_DETERMINISTIC(que quería averiguar).
Tomasz Gandor
18

Esto es válido en 2008 R2 por lo que SSMS genera cuando se escribe un DROP de una función:

SELECT  *
FROM    sys.objects
WHERE   type IN (N'FN', N'IF', N'TF', N'FS', N'FT') ;

/*
From http://msdn.microsoft.com/en-us/library/ms177596.aspx:
 FN SQL_SCALAR_FUNCTION
 FS Assembly (CLR) scalar-function
 FT Assembly (CLR) table-valued function
 IF SQL_INLINE_TABLE_VALUED_FUNCTION
 TF SQL_TABLE_VALUED_FUNCTION
*/
Orlando Colamatteo
fuente
1
Su sugerencia de edición debe ser un comentario, no una edición. la "función AF Aggregate" es claramente de la documentación de MS (verifique el enlace), por lo que esta publicación parece completamente correcta. Si no está de acuerdo: comente . Ha notado. Si la gente rechaza continuamente su edición de este debe ser un indicio de que se está quizás haciendo algo mal, y no las otras personas.
Martin Tournoij
@Carpetsmoker "AF" no se considera una "función" en términos de los metadatos del objeto de SQL Server, aunque significa AGGREGATE_FUNCTION. Es más claro que un agregado es un tipo de objeto diferente de otras funciones definidas por el usuario cuando se considera que crea un nuevo agregado usando CREAR AGREGADO en lugar de CREAR FUNCIÓN. Los tipos de objeto 'FN', 'IF', 'TF', 'FS' y 'FT' son los cinco tipos de funciones por lo que SSMS (a través de SMO) genera cuando se escribe el código SI EXISTS ... DROP FUNCTION. Debe aceptar mi edición para revertir la adición incorrecta de AF a la lista de tipos de funciones de SQL Server.
Orlando Colamatteo
5

Es un poco más detallado, pero esto debería hacer exactamente lo mismo:

select * from sys.objects where (type='TF' or type='FN')

Por lo que puedo ver, tampoco está en SQL Server 2008.

Ayresome
fuente
1
Sí, eso es lo que básicamente hice yo mismo para crear una vista "sys_functions" :-) Me pregunto por qué no está en el producto fuera de la caja ...
marc_s
4

Esto no agrega nada nuevo, pero encontré lo siguiente más fácil de recordar:

select * from sys.objects where type_desc like '%fun%'
yoniLavi
fuente
Si el código de poste, XML o datos de muestras, por favor, destacar aquellas líneas en el editor de texto y haga clic en el botón "muestras de código" ( { }) en la barra de herramientas de editor de formato y la sintaxis muy bien resáltala!
marc_s
Gracias, pero trato de evitar el "tenerlo todo" sys.objectstanto como puedo.
marc_s
4

prueba esto :

SELECT * FROM sys.objects
where type_desc = 'SQL_SCALAR_FUNCTION'
vishal kadam
fuente
2

por cierto, ¿no le gustaría incluir type = 'FS'?

name    type    type_desc
getNewsletterStats  FS  CLR_SCALAR_FUNCTION

eso es lo que corresponde al elemento en sys.objects para mi UDF que se deriva de una DLL externa


fuente
2

Para ampliar la respuesta de @ LukeH, para devolver las definiciones de función también se requiere una combinación a la sys.sql_modulestabla. Entonces la consulta para esto es:

SELECT O.name as 'Function name', M.definition as 'Definition', O.object_id
FROM sys.objects as O INNER JOIN sys.sql_modules as M
    ON O.object_id = M.object_id
WHERE type IN ('FN', 'IF', 'TF')  -- scalar, inline table-valued, table-valued

donde lo anterior muestra el nombre de la función, su definición y el identificador de objeto respectivamente.

Caballero de la Luna
fuente
2

Para obtener una descripción más completa de las funciones escalares, incluido el propietario y el tipo de retorno:

SELECT f.name, s.name AS owner, t.name as dataType, p.max_length, p.precision, p.scale, m.definition
FROM sys.objects f
JOIN sys.schemas s on s.schema_id = f.schema_id
JOIN sys.parameters p on p.object_id = f.object_id AND p.parameter_id = 0
JOIN sys.types t ON t.system_type_id = p.system_type_id 
JOIN sys.sql_modules as m ON m.object_id = f.object_id
WHERE type='FN';
Peter Brand
fuente
0

SQL 2000 ligero ajuste específico para el nombre del objeto:

SELECT *
FROM sysobjects
WHERE type IN ('FN', 'IF', 'TF')

O

SELECT *
FROM dbo.sysobjects
WHERE type IN ('FN', 'IF', 'TF')
Goran B.
fuente