2009-01-27 110 views
6

任何想法是否可以使用单独的T-SQL在其他数据库中创建过程,其中数据库的名称先前未知且必须从表中读取?有点像这个例子:在另一个数据库中创建存储过程

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) 

看看我在做什么?这个例子失败了,因为Go实际上不是一个T-SQL命令,但它被查询分析器/ SQL管理工作室识别并产生错误。删除Go并且它也失败,因为Create Proc必须是脚本的第一行。 Arrgg!

T-SQL的语法不允许你做这样的事情:

创建[OtherDatabase] [DBO] [测试]

这是一种耻辱,因为它会工作一种享受。 !你可以做到这一点与Select语句,耻辱是不一致的:

SELECT * FROM [OtherDatabase] .. [TheTable]

干杯,罗布。

+0

如果你第一次更改数据库EXEC然后exec的你storedproc? – 2009-01-27 15:25:02

+0

我也会这样做:首先发送零件之前“去”,然后(在第二个SQL语句)发送“创建proc ...” – 2009-01-29 13:15:58

回答

16

这是一种痛苦,但这就是我所做的。我把这个从一个例子,我在sqlteam发现,我想 - 你可能有我做滥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) 
0

你可以使用xp_cmdshell将其转换为osql,我想。

0

我不认为这可以用TSQL来完成。

您可以使用一个SSIS包,它环绕名称并动态连接到服务器,从而创建您需要的架构(procs)。

这可能是我会做的,因为它意味着它全部包含在包中。

通过使用包含要部署模式的服务器/数据库列表的表或外部xml文件,可以使配置保持独立。

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

这是我如何与阿尔特程序进行:

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)