SQL Server - onde está “sys.functions”?

104

O SQL Server 2005 tem ótimas exibições sys.XXX no catálogo do sistema, que eu uso com frequência.

O que me confunde é o seguinte: por que há uma exibição "sys.procedures" para ver informações sobre seus procedimentos armazenados, mas não há uma exibição "sys.functions" para ver o mesmo para suas funções armazenadas?

Ninguém usa funções armazenadas? Acho que são muito úteis, por exemplo, para colunas computadas e coisas do gênero!

Existe um motivo específico para a falta de sys.functions ou é apenas algo que não foi considerado importante o suficiente para ser colocado nas visualizações do catálogo sys ?? Está disponível no SQL Server 2008 ??

Saúde, Marc

marc_s
fonte
A resposta fornecida por TimC (respondida em 22 de janeiro às 14:06) é preferível ao uso da tabela de sistema sysobjects mais antiga, porque você tem uma coluna LAST_ALTERED em INFORMATION_SCHEMA.ROUTINES que é semelhante à coluna modify_date que existe em sys.tables, sys.views, sys.procedures, etc. No entanto, se estiver usando a exibição do sistema sys.objects mais atualizada, você tem modify_date como nessas tabelas. Meus $ 0,02. Saúde,
-Matthew
1
@JuniorMayhe: ok - aqui está o feedback da sugestão do Connect que eu inscrevi - avalie ! :-)
marc_s
1
Acho que @marc_s tem um bom argumento: muitas pessoas não conseguem entender por que não existe sys.functions. Você tem sys.foreign_keyse não sys.primary_keys. De qualquer forma, peço a vocês que usem o canal aberto da Microsoft para propor e sugerir novos recursos para as próximas versões do SQL Server em connect.microsoft.com/SQLServer/Feedback . Já adicionei um feedback sobre sys.functions em connect.microsoft.com/ SQLServer / feedback / details / 1127920
Junior Mayhé

Respostas:

117

Eu acho que os UDFs são muito úteis e eu os uso o tempo todo.

Não tenho certeza de qual é o fundamento lógico da Microsoft para não incluir um equivalente sys.functions no SQL Server 2005 (ou SQL Server 2008, pelo que posso dizer), mas é fácil de criar o seu próprio:

CREATE VIEW my_sys_functions_equivalent
AS
SELECT *
FROM sys.objects
WHERE type IN ('FN', 'IF', 'TF')  -- scalar, inline table-valued, table-valued
LukeH
fonte
7
Isso também deve incluir os tipos de função CLR: 'AF', 'FS' e 'FT'. Consulte a descrição da coluna "tipo" de sys.objects
Triynko
4
"AF" não é considerado uma "função" em termos de metadados de objeto do SQL Server, embora signifique AGGREGATE_FUNCTION. É mais claro que um Aggregate é um tipo de objeto diferente de outras funções definidas pelo usuário ao considerar que você cria um novo agregado usando CREATE AGGREGATE em vez de CREATE FUNCTION. Os tipos de objeto 'FN', 'IF', 'TF', 'FS' e 'FT' são os cinco tipos de função que o SSMS (via SMO) gera ao criar o código IF EXISTS ... DROP FUNCTION.
Orlando Colamatteo
37

Outra maneira de listar funções é usar as visualizações INFORMATION_SCHEMA.

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

De acordo com o site da Microsoft, "As visualizações do esquema de informações fornecem uma visualização interna independente da tabela do sistema dos metadados do SQL Server. As visualizações do esquema de informações permitem que os aplicativos funcionem corretamente, embora mudanças significativas tenham sido feitas nas tabelas do sistema subjacentes". Em outras palavras, as tabelas de sistema subjacentes podem mudar conforme o SQL é atualizado, mas as visualizações ainda devem permanecer as mesmas.

Tim C
fonte
Sim, obrigado, eu conheço o INFORMATION_SCHEMA também - mas como usuário de longa data, sys.xxxx ainda é mais fácil - obrigado pelo lembrete!
marc_s
4
INFORMATION_SCHEMA seria ótimo, mas não inclui o corpo inteiro de procedimentos maiores - o que o torna menos do que inútil se você estiver pesquisando no corpo. Não é o que você não sabe que vai te colocar em apuros, mas o que você sabe que não é ...
jmoreno
3
As visualizações de Information_Schema são expressamente documentadas como não sendo confiáveis ​​para algumas coisas. por exemplo, "Não use visualizações INFORMATION_SCHEMA para determinar o esquema de um objeto. A única maneira confiável de encontrar o esquema de um objeto é consultar a visualização do catálogo sys.objects." em msdn.microsoft.com/en-us/library/ ms188757.aspx
David Eison
Eu gosto dessa resposta, porque a INFORMATION_SCHEMAconsulta retorna resultados muito interessantes como IS_DETERMINISTIC(que eu queria descobrir).
Tomasz Gandor
18

Isso é válido em 2008 R2 de acordo com o que o SSMS gera quando você faz um script DROP de uma função:

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
fonte
1
Sua sugestão de edição deve ser um comentário, não uma edição. a "função AF Aggregate" é claramente da documentação da MS (verifique o link), então este post parece totalmente correto. Se você discordar: comente . Observou que. Se as pessoas rejeitaram repetidamente sua edição, isso deve ser uma dica de que talvez você esteja fazendo algo errado, e não as outras pessoas.
Martin Tournoij
@Carpetsmoker "AF" não é considerada uma "função" em termos de metadados de objeto do SQL Server, embora signifique AGGREGATE_FUNCTION. É mais claro que um Aggregate é um tipo de objeto diferente de outras funções definidas pelo usuário ao considerar que você cria um novo agregado usando CREATE AGGREGATE em vez de CREATE FUNCTION. Os tipos de objeto 'FN', 'IF', 'TF', 'FS' e 'FT' são os cinco tipos de função que o SSMS (via SMO) gera ao criar o código IF EXISTS ... DROP FUNCTION. Você deve aceitar minha edição para reverter a adição incorreta de AF à lista de tipos de função do SQL Server.
Orlando Colamatteo
5

É um pouco mais detalhado, mas deve fazer exatamente a mesma coisa:

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

Pelo que posso ver, também não está no SQL Server 2008.

Ayresome
fonte
1
Sim, isso é o que eu basicamente fiz para criar uma visão "sys_functions" :-) Apenas me perguntando por que não está no produto pronto para uso ....
marc_s
4

Isso não acrescenta nada de novo, mas achei o seguinte mais fácil de lembrar:

select * from sys.objects where type_desc like '%fun%'
yoniLavi
fonte
Se você código postal, amostras de XML ou de dados, por favor destacar as linhas no editor de texto e clique no botão "código de amostras" ( { }) na barra de ferramentas do editor de bem formato e sintaxe destacá-lo!
marc_s
Obrigado, mas tento evitar o "tem-tudo" sys.objectstanto quanto posso.
marc_s
4

tente isto:

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

aliás, você não gostaria de incluir type = 'FS'?

name    type    type_desc
getNewsletterStats  FS  CLR_SCALAR_FUNCTION

é a isso que o item em sys.objects corresponde para meu UDF, que é derivado de uma DLL externa


fonte
2

Para estender a resposta de @ LukeH, retornar as definições da função também requer uma junção à sys.sql_modulestabela. Portanto, a consulta para isso é:

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

onde o acima exibe o nome da função, sua definição e o identificador do objeto respectivamente.

Cavaleiro da Lua
fonte
2

Para uma descrição mais completa das funções escalares, incluindo proprietário e 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
fonte
0

SQL 2000 pequeno ajuste específico para o nome do objeto:

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

OU

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