2009-01-27 19 views
6

¿Alguna idea de si es posible crear un procedimiento en otra base de datos usando solo T-SQL, donde el nombre de la base de datos no se conoce desde el principio y debe leerse desde una tabla? Algo así como este ejemplo:Crear procedimiento almacenado en otra base de datos

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) 

¿Ves lo que estoy tratando de hacer? Este ejemplo falla porque Go no es realmente un comando T-SQL, sino algo reconocido por el analizador de consultas/el estudio de administración SQL y produce un error. Quite Go y también falla porque Create Proc debe ser la primera línea del script. Arrgg !!

La sintaxis de T-SQL no le permite hacer cosas como esta:

Crear [OtherDatabase] [dbo] [Test]

Lo cual es una lástima, ya que funcionaría un convite.. ! Usted puede hacer eso con instrucciones SELECT, la vergüenza es inconsistente:

Select * From [OtherDatabase] .. [thetable]

Cheers, Rob.

+0

¿Qué pasaría si el cambio primera base de datos con el ejecutivo y luego Exec storedproc? –

+0

Lo haría así también: primero envíe la parte antes de "ir", luego (en una segunda instrucción SQL) envíe "crear proceso ..." –

Respuesta

16

Es un dolor, pero esto es lo que hago. Que tomé de un ejemplo que encontré en sqlteam, creo - es posible que tenga algunos problemas de cotización con la forma en que hice la indiscriminada 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, sí, puedo ver que funciona. Un ejecutivo dentro y Exec. ¡Chico, las citas se pondrán peludas! –

0

Podría pagar a osql usando xp_cmdshell, supongo.

0

no creo que esto se puede hacer con TSQL.

Puede usar un paquete SSIS que enlazó los nombres y se conectó dinámicamente a los servidores, lo que crea el esquema (procs) que necesita.

Esto es probablemente lo que haría, ya que significa que está todo dentro del paquete.

La configuración puede mantenerse separada utilizando una tabla o un archivo xml externo que contenga la lista de servidor/bases de datos para implementar el esquema.

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

Así es como yo he hecho con Alter Procedimiento:

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) 
Cuestiones relacionadas