Est-il possible de spécifier de manière conditionnelle la database dans un nom de table complet dans T-SQL?

Au travail, nous avons trois environnements de database SQL Server 2008 R2: production, test et développement.

Dans l'environnement de production, différentes parties de notre système s'exécutent sur 3 servers de bases de données différents (appelons-les PROD1 , PROD2 et PROD3 ), tandis que dans l'environnement de développement, toutes les bases de données fonctionnent sur le même server.

Ce n'est normalement pas un problème, car la plupart de notre code SQL n'a pas besoin de se référer à des objects en dehors de sa propre database. Mais dans une poignée de cas, une vue ou une procédure stockée doit se référer à une table, une vue ou une fonction qui réside non seulement dans une autre database, mais dans une database sur un server de production différent. C'est à dire que nous avons une vue sur PROD3 qui a besoin de chercher un user dans la list des users sur PROD1 comme ceci:

 PROD1.UserDB.UserSchema.UserList 

Bien sûr, cela nous pose des problèmes dans l'environnement de test, car nous avons besoin de ces vues / procédures stockées pour faire reference à différents servers, en fonction de leur location.

Ma question: est-il possible d'avoir des valeurs conditionnelles dans un nom de table complet ( ServerName.DatabaseName.SchemaName.TableName ) dans T-SQL? Je pourrais avoir quelque chose comme ça (PROD1|DEV1).UserDB.UserSchema.UserList dans une vue ou une procédure stockée? Ou peut-être d'une certaine manière get le nom du server à partir d'une variable, que nous pourrions ensuite définir en fonction du server actuel?

Question bonus: dans un cas, nous devons même changer le nom de la database. Cela peut-il être fait de la même manière?

Je me rends count que nous pourrions contourner cela en créant une instruction SQL dynamic dans une string, puis en l'exécutant. Mais pour diverses raisons, nous aimerions beaucoup éviter cette approche.

Comme déjà mentionné, vous avez besoin d'utiliser le SQL dynamic. Mais vous pouvez l'utiliser pour la création de l'object: simplement créer le synonyme dans le SQL dynamic pour tous les objects qui doivent être accessibles à partir d'un autre server et / ou d'une autre database.

Dans ce cas, tout votre code sera statique et seulement pendant le process d'installation / deployment utilisant le SQL dynamic l'object nécessaire sera référencé.

Le code peut être comme suit:

 declare @sql nvarchar(max) if @@servername = 'DEV1' set @sql = 'create synonym vUserList for [Dev1].UserDB.UserSchema.UserList' else set @sql = 'create synonym vUserList for [PROD1].UserDB.UserSchema.UserList' exec sp_executesql @sql 

Et tout votre code (SP, fonctions, etc.) peut utiliser ce synonyme – vUserList

De la même manière, vous pouvez modifier le nom de la database ciblée en fonction de l'environnement – test, dev ou prod

Pour les references de bases de données croisées, votre meilleur pari pourrait être l'utilisation de synonymes . La définition des synonymes sera différente entre DEV et PROD, mais la définition des objects complexes (vues, SP, etc.) qui utilisent les synonymes peut restr inchangée.

Vous voulez une combinaison de servers liés et d' alias de server .