Nous avons un très vieux logiciel qui a été créé il y a environ 10 ans et nous n'avons pas de code source.
Le logiciel utilise deux bases de données, DB01
et DB02
sur la même instance SQL Server 2012.
Il existe des instructions SQL telles que db01..table1 join db02..table2
, mais le problème principal est que nos processus ne nous permettent pas d'utiliser db02
comme nom de base de données.
La question est: comment créer un alias de for database?
J'essayais d'utiliser CREATE SYNONYM
CREATE SYNONYM [db02] FOR [db02_new_name];
mais cela ne fonctionne pas pour les noms de base de données.
Veuillez suggérer comment cela peut être résolu sans patcher un fichier binaire pour corriger les instructions SQL.
Créez une base de données avec le nom que vous souhaitez emprunter. Redéfinissez le générateur de code DDL pour créer une vue pour chaque table de la base de données contenant les tables auxquelles j'ai besoin d'accéder via le nom codé en dur. Fondamentalement, chaque vue aura une déclaration qui ressemble à ceci.
CREATE VIEW schemaname.tablename as SELECT * FROM targetdbname.schemaname.tablename
Exemple:
Le nom de la base de données cible codé en dur est appelé ProdDBV1
et la base de données source que vous avez est nommée ProductDatabaseDatabaseV1
, le schéma est dbo
et le nom de la table est customer
ProdDBV1
en utilisant SSMS ou un script.CREATE VIEW dbo.customer as SELECT * FROM ProductDatabaseDatabaseV1.dbo.customer
Si vous pouvez énumérer chaque table de votre base de données "source", puis créer le DDL comme ci-dessus. Si vous le souhaitez, je peux mettre à jour cette publication avec un exemple de code. (en utilisant le sp_msforeachtable
procédure si possible)
J'ai eu un problème similaire.
Résolu avec ceci solution de contournement , en utilisant des synonymes.
Version courte: Vous inonder votre base de données avec un synonyme de chaque objet que vous aurez jamais besoin de référencer. Plus tard, vous recréez chaque synonyme avec l'autre nom de base de données.
Voici un proc stocké pour le faire. Ajoutez-le simplement à votre base de données et appelez-le avec la base de données cible. Il créera des synonymes pour toutes les tables de la base de données cible et créera les schémas s'ils n'existent pas. J'ai laissé une section commentée au cas où quelqu'un connaîtrait un moyen de faire fonctionner les schémas de création sans curseur.
CREATE PROCEDURE CreateSynonymsForTargetDatabase (
@databaseName sysname
)
AS BEGIN
DECLARE @TSQL nvarchar(max) = N''
DECLARE @rn char(2),
@SchemaName sysname;
SET @rn = char(13) + char(10)
CREATE TABLE #DBSynonym(
[Schema] sysname NOT NULL,
[Table] sysname NOT NULL
)
SET @TSQL = N'
INSERT INTO #DBSynonym ([Schema], [Table])
SELECT Schemas.name, Tables.name
FROM [' + @databaseName + '].sys.tables
INNER JOIN [' + @databaseName + '].sys.schemas on tables.schema_id = schemas.schema_id
'
EXEC (@TSQL)
SET @TSQL = N''
DECLARE MissingSchemasCursor CURSOR
READ_ONLY
FOR
SELECT newSchemas.[Schema]
FROM #DBSynonym newSchemas
LEFT JOIN sys.schemas on newSchemas.[Schema] = schemas.name
WHERE schemas.schema_id is null
GROUP BY newSchemas.[Schema]
OPEN MissingSchemasCursor
FETCH NEXT FROM MissingSchemasCursor INTO @SchemaName
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
SET @TSQL = N'CREATE SCHEMA ' + QUOTENAME(@SchemaName) + N';'
EXEC sp_executesql @TSQL
END
FETCH NEXT FROM MissingSchemasCursor INTO @SchemaName
END
CLOSE MissingSchemasCursor
DEALLOCATE MissingSchemasCursor
/*
SELECT @TSQL = @TSQL +
N'
GO
CREATE SCHEMA ' + QUOTENAME([Schema]) + N';'
FROM #DBSynonym newSchemas
LEFT JOIN sys.schemas on newSchemas.[Schema] = schemas.name
WHERE schemas.schema_id is null
GROUP BY newSchemas.[Schema]
PRINT 'CREATE SCHEMAS : ' + ISNULL(@TSQL,'')
EXEC sp_executesql @TSQL
*/
SET @TSQL = N''
SELECT @TSQL = @TSQL +
N'
CREATE SYNONYM ' + QUOTENAME([Schema]) + N'.' + QUOTENAME([Table]) + N'
FOR ' + QUOTENAME(@databaseName) + N'.' + QUOTENAME([Schema]) + N'.' + QUOTENAME([Table]) + N';'
FROM #DBSynonym
EXEC sp_executesql @TSQL
SET @TSQL = N''
END
GO
Utilisez-le comme suit:
EXEC CreateSynonymsForTargetDatabase 'targetDbName'
La question est: comment créer un alias de for database?
Je sais que c'est un ancien poste mais ...
C'est pourquoi j'utilise uniquement la convention de dénomination en 2 parties pour les objets SQL. Cela me permet d'avoir des synonymes en 2 parties qui pointent vers des bases de données nommées différemment selon l'environnement dans lequel je me trouve. Il y a des endroits où cela ne fonctionne pas si bien mais, pour la plupart, ces endroits sont très rares.
En ce qui concerne les logiciels dont vous n'avez pas le code source et si ce logiciel utilise la convention de dénomination en 3 parties, vous n'avez probablement pas de chance, sauf si vous savez quelle est la convention de dénomination en 3 parties pour chaque objet et créez une partie en 3 parties synonyme de chaque objet.
Accédez à la base de données que vous souhaitez créer Alias,
Créez une table de dossiers d'alias avec la conception préférée,
Accédez à la table des ID uniques et vérifiez la dernière séquence de code pour la table créée.
Par exemple, si le dernier code est 10, mettez-le à jour à 11.
Ouvrez la table des armoires et allez tout en bas et créez le nom de l'armoire Alias que vous souhaitez.
J'ai trouvé la réponse de Charles (et la solution de contournement liée dans le commentaire de maxcastaneda) très utile. J'ai suivi cette approche et cela fonctionne pour moi. Je l'ai un peu rationalisé et créé la requête suivante qui affiche tous les synonymes requis pour créer.
Comme condition préalable à cet extrait de code, la base de données d'origine et le synonyme/alias db doivent être sur le même serveur, sinon, si vous utilisez un serveur lié ou si vous devez le modifier un peu. Il devrait être assez facile de mettre cela dans un petit sp pour mettre à jour automatiquement les synonymes.
USE <SYNONYMDB>
SELECT
'[' + TABLE_NAME + ']',
'[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']',
'IF EXISTS (SELECT * FROM sys.synonyms WHERE name = ''' + TABLE_NAME + ''') DROP SYNONYM ['+ TABLE_NAME + ']; CREATE SYNONYM [' + TABLE_NAME + '] FOR <ORIGINALDB>.' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']' AS SynonymUpdateScript FROM <ORIGINALDB>.INFORMATION_SCHEMA.TABLES
N'oubliez pas de saisir vos noms Db aux <...> spots.
Copiez simplement le contenu de la colonne SynonymUpdateScript
et exécutez-le dans la base de données synonyme - ou créez une procédure stockée pour cette tâche.
Soyez conscient qu'il y a un problème si vous avez des vues en place qui font référence à des tables ou à d'autres objets db sans la convention de dénomination en 2 parties. Ces synonymes ne fonctionneront pas. Vous devez corriger cela dans les objets/vues d'origine.