É possível definir de alguma forma rotinas disponíveis globalmente? Parece que toda rotina deve ser criada em um escopo do banco de dados.
Quando tentei criar uma rotina a partir do console (sem emissão prévia use dbname
), estou recebendo um erro:
ERROR 1046 (3D000): No database selected
Temos toneladas de bancos de dados idênticos (os dados são diferentes) e o objetivo é criar alguns gatilhos para alguns nomes de tabela. Mas queremos executar apenas uma rotina para não precisarmos criar essas rotinas para cada banco de dados (uma vez que são idênticas, as rotinas funcionariam da mesma forma para cada banco de dados).
mysql
stored-procedures
trigger
functions
bakytn
fonte
fonte
Respostas:
Não há como definir procedimentos armazenados ou funções armazenadas (ou eventos) que são globais.
Uma abordagem é criar um esquema comum compartilhado e qualificar as chamadas para as funções e procedimentos com o nome desse esquema (
CALL shared.the_procedure();
).Isso é algo que faço com minha coleção de funções personalizadas de cálculo de data / hora (por exemplo,
SELECT date_time.next_quarter_start_after(NOW())
) e com a sempre tão útil estrutura common_schema , que, é claro, vive em `common_schema`.Se você seguir essa abordagem, lembre-se de que, quando uma rotina está em execução, o banco de dados "atual" muda automaticamente e o valor de retorno da
DATABASE()
função retorna o nome do esquema sob o qual a rotina foi definida, e não o banco de dados atual da sua sessão . Ele muda de volta quando a rotina sai, portanto, se usado em um gatilho, não quebra nada ao seu redor, mas você não tem como saber de dentro da rotina qual era o banco de dados atual, se necessário.fonte
Apenas para expandir um pouco a resposta do @ Michael, mas enquanto referenciar um esquema comum é o caminho a seguir, você pode criar "aliases" nos bancos de dados locais para facilitar um pouco o gerenciamento.
Por exemplo, estou trabalhando com um derivado do MySQL que ainda não possui a
UUID_TO_BIN
função do MySQL 8 , então criei o meu e o armazenei em um banco de dados especificamente para coisas globais que chameicommon
. Portanto, para fazer referência a essa função, agora tenho que usarcommon.UUID_TO_BIN
em todas as minhas consultas e procedimentos armazenados. Não é um problema enorme, mas não tão fácil quanto simplesmente chamarUUID_TO_BIN
(como faria se a função nativa estivesse disponível).Então, o que eu fiz também foi adicionado um "alias" a cada um dos meus bancos de dados da seguinte forma:
Dessa forma, em cada banco de dados que adiciono esse "pseudônimo", agora posso simplesmente chamar
UUID_TO_BIN(some_uuid, TRUE)
sem nenhum nome de banco de dados adicionado, mas sem o incômodo de duplicar a função inteira, ou seja, se eu precisar alterar ou otimizar a função por algum motivo, apenas precisa fazer isso em um único lugar (common.UUID_TO_BIN
) em vez de atualizar todos os bancos de dados.Se eu atualizar posteriormente para um banco de dados com um nativo
UUID_TO_BIN
, também posso simplesmente remover todas as minhas funções de "alias" e todas as minhas consultas e procedimentos existentes agora o usarão sem nenhuma modificação adicional. Ou, se a função global fosse movida para um banco de dados diferente, só preciso atualizar meus aliases, em vez de todas as minhas consultas que a utilizam.Não sei ao certo quão inteligente é o MySQL quando se trata de otimizar uma função que simplesmente chama outra função; portanto, pode haver um pequeno custo associado ao redirecioná-lo dessa maneira, mas acho que vale a pena pelo gerenciamento simplificado. mantendo apenas uma única definição "global".
fonte
Uma abordagem muito simples é esta:
select [databasename].empstatus(empid) as status
;Script PHP:
fonte