Vou ter que discordar de Aaron (e a resposta aceita).
A abordagem de Aaron é a maneira como gosto de lidar com "coisas de DBA", por exemplo, scripts de manutenção. Eu nunca iria querer fazer isso com uma função de biblioteca que seria chamada por um banco de dados do usuário.
Por quê? Você estará indo para o equivalente de banco de dados da DLL Hell .
Versões incompatíveis
... Antes do Windows 2000, o Windows era vulnerável a isso porque a tabela de classes COM era compartilhada entre todos os usuários e processos. Somente um objeto COM, em uma DLL / EXE, pode ser declarado como tendo um ID de classe COM global específico em um sistema. Se algum programa precisasse criar uma instância dessa classe, obteria a implementação atual registrada centralmente. Como resultado, uma instalação de um programa que instala uma nova versão de um objeto comum pode inadvertidamente interromper outros programas que foram instalados anteriormente.
Instale o .net 4.5 em um servidor executando um aplicativo .net 2.0 e o que acontece? Nada, seu aplicativo continua usando a estrutura 2.0. Atualize sua função LastIndexOf em um servidor que hospeda 3 bancos de dados de aplicativos (como parte de uma atualização para um deles) e o que acontece? Todos os três agora estão usando a versão mais recente.
A alternativa é a abordagem adotada pelo SQL # . Isso é instalado em um esquema em cada banco de dados do usuário, para que você possa atualizar com segurança o banco de dados do Aplicativo-X sem arriscar a estabilidade do Aplicativo-Y.
Se você estiver trabalhando em um ambiente de gerenciamento de mudanças rigidamente controlado, não terá escolha, não poderá atualizar um componente compartilhado sem testar todos os consumidores do componente. Se você estiver trabalhando em algum lugar um pouco mais "rápido e solto", poderá correr o risco de quebrar algo sem querer com um patch / atualização.