Создание хранимой процедуры в другой базе данных - PullRequest
9 голосов
/ 27 января 2009

Есть идеи, если возможно создать процедуру в другой базе данных, используя только 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 должен быть первой строкой скрипта. Arrgg !!

Синтаксис T-SQL не позволяет вам делать такие вещи:

Создать [OtherDatabase]. [Dbo]. [Test]

Какой позор, потому что это доставит удовольствие! Вы можете сделать это с помощью операторов Select, к сожалению, это противоречиво:

Выбрать * Из [OtherDatabase] .. [TheTable]

Приветствия, Роб.

Ответы [ 5 ]

19 голосов
/ 27 января 2009

Это боль, но это то, что я делаю. Я взял это из примера, который я нашел в 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)
9 голосов
/ 27 апреля 2009
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
2 голосов
/ 11 ноября 2014

Вот как я это сделал с помощью процедуры Alter:

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)
0 голосов
/ 28 января 2009

Не думаю, что это можно сделать с помощью TSQL.

Вы можете использовать пакет служб SSIS, который зацикливает имена и динамически подключается к серверам, что создает необходимую схему (процедуры).

Это, вероятно, то, что я хотел бы сделать, поскольку это означает, что все это содержится в пакете.

Конфигурацию можно хранить отдельно, используя таблицу или внешний XML-файл, содержащий список серверов / баз данных для развертывания схемы.

0 голосов
/ 27 января 2009

Вы могли бы раскошелиться на osql, используя xp_cmdshell, я полагаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...