Acho que há algo que estou perdendo quando se trata de qual banco de dados está sendo usado ao executar um procedimento armazenado de sistema personalizado. Eu tenho o seguinte em meu procedimento armazenado (editado para brevidade):
ALTER PROCEDURE sp_mysp
AS
IF (EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'mytable'))
BEGIN
--Do stuff to the table
END
ELSE
BEGIN
PRINT 'Table mytable does not exist'
END
O problema é que quando eu chamo o procedimento de mydb, a tabela Master é usada para a verificação inicial, ao invés do banco de dados atual. Se eu escrever mydb.INFORMATION_SCHEMA.TABLES funcionará, mas isso não é realmente uma solução, pois está derrotando todo o objetivo de manter isso como um único SP em vez de um SP para cada banco de dados.
Alguma ideia? Tentei passar o nome do banco de dados como parâmetro e iniciar o SP com 'use @db_name', mas aparentemente os procedimentos armazenados não permitem instruções de uso.
Agradecemos antecipadamente por toda a ajuda.
Você precisa marcar seu procedimento armazenado como um objeto do sistema para obter o comportamento desejado (exemplo completo abaixo testado como funcionando em 2008 SP3)
Esta é uma abordagem não documentada e pode não funcionar em versões futuras.
Alternativa: usando SQL dinâmico. E não, na funcionalidade de administração controlada, o SQL dinâmico não é a coisa má que costuma ser.
Agora sua chamada de qualquer outro banco de dados pode ser:
Ou simplesmente:
Você pode até criar um sinônimo no modelo (e em todos os bancos de dados existentes) da seguinte forma:
(Agora você pode retirar o prefixo das chamadas acima.)
Embora sua chamada seja uma etapa mais complexa, os benefícios dessa abordagem: