2009-01-27 8 views
6

Aucune idée s'il est possible de créer une procédure dans une autre base de données uniquement avec T-SQL, où le nom de la base de données n'est pas connu et doit être lu depuis une table? Un peu comme cet exemple:Création d'une procédure stockée dans une autre base de données

Use [MasterDatabase] 
Declare @FirstDatabase nvarchar(100) 
Select Top 1 @FirstDatabase=[ChildDatabase] From [ChildDatabases] 
Declare @SQL nvarchar(4000) 
Declare @CRLF nvarchar(10) Set @CRLF=nchar(13)+nchar(10) 
Set @SQL = 
    'Use [+'@Firstdatabase+']'[email protected]+ 
    'Go'[email protected]+ 
    'Create Proc [Test] As Select 123' 
Exec (@SQL) 

Voir ce que je suis en train de faire? Cet exemple échoue parce que Go n'est en réalité pas une commande T-SQL mais quelque chose reconnu par l'analyseur de requête/le studio de gestion SQL et produit une erreur. Supprimer le Go et il échoue également parce que Create Proc doit être la première ligne du script. Arrgg !!

La syntaxe de T-SQL ne vous permet pas de faire des choses comme ceci:

Créer [OtherDatabase] [dbo] [Test]

Ce qui est dommage car il travaillerait un régal.. ! Vous pouvez le faire avec les instructions Select, dommage qu'il est incompatible:

Select * From [OtherDatabase] .. [theTable]

Cheers, Rob.

+0

Que faire si vous la première base de données de changement avec exec puis exec vous storedproc? –

+0

Je le ferais aussi comme ceci: d'abord envoyer la partie avant "go", puis (dans une seconde instruction SQL) envoyer "créer proc ..." –

Répondre

16

C'est une douleur, mais c'est ce que je fais. Je pris ce à partir d'un exemple que je trouve sur sqlteam, je pense - vous pourriez avoir quelques problèmes avec la façon dont citant je l'ai fait l'aveugle REPLACE:

DECLARE @sql AS varchar(MAX) 
DECLARE @metasql as varchar(MAX) 
DECLARE @PrintQuery AS bit 
DECLARE @ExecQuery AS bit 

SET @PrintQuery = 1 
SET @ExecQuery = 0 

SET @sql = 
' 
CREATE PROCEDURE etc. 
AS 
BEGIN 
END 
' 

SET @metasql = ' 
USE OtherDatabase 
EXEC (''' + REPLACE(@sql, '''', '''''') + ''') 
' 

IF @PrintQuery = 1 
    PRINT @metasql 
IF @ExecQuery = 1 
    EXEC (@metasql) 
+1

Hmm, oui je peux voir que le travail. Un Exec à l'intérieur et Exec. Garçon sera la citation devenir poilue! –

0

Vous pouvez extraire vers osql en utilisant xp_cmdshell, je suppose.

0

Je ne pense pas que cela peut être fait avec TSQL.

Vous pouvez utiliser un package SSIS qui a bouclé les noms et connecté dynamiquement aux serveurs, ce qui crée le schéma (procs) dont vous avez besoin.

C'est probablement ce que je ferais car cela signifie que tout est contenu dans le paquet.

La configuration peut être conservée séparément en utilisant une table ou un fichier xml externe contenant la liste des serveurs/bases de données dans lesquels le schéma doit être déployé.

7
DECLARE @UseAndExecStatment nvarchar(4000), 
     @SQLString nvarchar(4000) 

SET @UseAndExecStatment = 'use ' + @DBName +' exec sp_executesql @SQLString' 

SET @SQLString = N'CREATE Procedure [Test] As Select 123' 

EXEC sp_executesql @UseAndExecStatment, 
      N'@SQLString nvarchar(4000)', @[email protected] 
1

Voici comment je l'ai fait avec Alter Procédure:

DECLARE @metasql as varchar(MAX) 
DECLARE @sql AS varchar(MAX) 

SET @sql = 
'ALTER PROCEDURE [dbo].[GetVersion] 
    AS 
     BEGIN 
      SET NOCOUNT ON; 
      SELECT TOP(1)[Version] from VersionTable     
     END' 

SET @metasql = ' 
USE MyProdDb 
IF (OBJECT_ID(''GetVersion'') IS NOT NULL OR OBJECT_ID(''GetVersion'', ''P'') IS NOT NULL) 
BEGIN 
    EXEC (''' + REPLACE(@sql, '''', '''''') + ''') 
END 
' 
--PRINT @metasql 
EXEC (@metasql) 
Questions connexes