2009-01-27 108 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)