【问题标题】:Creating stored procedure in another database在另一个数据库中创建存储过程
【发布时间】:2009-01-27 15:17:09
【问题描述】:

知道是否可以单独使用 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+']'+@CRLF+
    'Go'+@CRLF+
    'Create Proc [Test] As Select 123'
Exec (@SQL)

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

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

创建 [OtherDatabase].[dbo].[Test]

这是一种耻辱,因为它会起作用!你可以用 Select 语句做到这一点,可惜它不一致:

Select * From [OtherDatabase]..[TheTable]

干杯,罗伯。

【问题讨论】:

  • 如果你先用 exec 改变数据库,然后再用 exec 你的存储过程呢?
  • 我也会这样做:首先发送“go”之前的部分,然后(在第二个 SQL 语句中)发送“create proc...”

标签: sql-server tsql stored-procedures


【解决方案1】:

这很痛苦,但这就是我所做的。我是从我在 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)

【讨论】:

  • 嗯,是的,我可以看到它工作。内部的 Exec 和 Exec。男孩的报价会变得毛茸茸的!
【解决方案2】:
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)', @SQLString=@SQLString

【讨论】:

  • 这是一种干净的方法,尽管我不得不将数据类型更改为 NVARCHAR(MAX)
【解决方案3】:

这就是我对 Alter Procedure 所做的:

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)

【讨论】:

    【解决方案4】:

    我想你可以使用 xp_cmdshell 向 osql 发送数据。

    【讨论】:

      【解决方案5】:

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

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

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

      可以通过使用表或外部 xml 文件(其中包含要部署架构的服务器/数据库列表)将配置分开。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多