2012-07-23 7 views
2

У меня есть две разные базы данных SQL Server (на том же сервере - если это помогает), которым необходимо разделить одну и ту же логику хранимых процедур. Решение, которое я пытаюсь достичь, выглядит так:Совместное использование хранимой процедуры в базе данных с использованием синонимов

Database1 
    Table: TestTable 
    Synonym: sp_MyProc pointing at SharedDatabase.dbo.sp_MyProc 

Database2 
    Table: TestTable 
    Synonym: sp_MyProc pointing at SharedDatabase.dbo.sp_MyProc 

SharedDatabase 
    Proc: sp_MyProc which runs queries against TestTable 

Моя надежда использовать синонимы, так что если я исполню sp_MyProc в то время как в контексте Database1, он будет использовать Database2.TestTable. И если я выполняю sp_MyProc, а в контексте Database2, это будет противоречить Database2.TestTable. Однако, когда я выполняю sp_MyProc через любой из синонимов, он игнорирует контекст синонима и выполняет поиск локальной копии TestTable, которая не найдена.

Есть ли способ реализовать общую хранимую процедуру, которая выполняется против разных копий таблиц в разных базах данных, либо через синонимы, либо какой-либо другой механизм?

Редактировать
Следует отметить, что в моем случае я ищу, чтобы сделать это с большим набором существующих таблиц и проки, так что любое решение, которое требует модификации проки или таблицы сами не являются идеальными.

+0

Это то, что я ищу. – Gisway

ответ

3

Что-то вроде этого будет работать для определения процедуры. Не забудьте защитить SQL-инъекцию, так как она построена динамически.

CREATE PROCEDURE [dbo].dosomething 
    @databaseName sysname, 
    @schema sysname, 
    @tableName sysname 
    as 
    declare @cmd as nvarchar(max) 
    set @cmd = N'select * from ' + quotename(@schema) + N'.' + quotename(@tableName) 
    exec sp_executesql @cmd 

Затем использовать его как это:

dosomething 'SampleDb', 'dbo', 'sampleTable' 
+0

Извините, я должен был упомянуть в своем вопросе, что я хочу сделать это с помощью очень большого и сложного набора существующих процессов. Поэтому изменение процесса для размещения не является вариантом. Но это правильный ответ на общий вопрос, так что +1. – RationalGeek

1

Если хранимая процедура находится в SharedDatabase, то он всегда будет работать в контексте SharedDatabase. Чтобы выполнить то, что вы пытаетесь сделать, чтобы централизовать код, я бы, возможно, передал параметр, чтобы указать, с какого сервера он идет, поэтому вы можете выполнить запрос к этому конкретному TestTable. В принципе, вам нужно будет обратиться к каждой таблице, используя их полное имя - то есть Database1.dbo.TestTable

 


    USE SharedDatabase 

    CREATE PROCEDURE [dbo].sp_MyProc 
    @dbsource varchar(50) 
    as 

    if(@dbsource == 'DB1') 
    begin 

    select * from Database1.dbo.TestTable 

    end 
    else 
    begin 

    select * from Database2.dbo.TestTable 

    end 


    GO 



 

Другой альтернативой является сделать вид в SharedDatabase, которая будет называться TestTableComposite, с дополнительной колонкой чтобы определить, где находятся исходные данные. А затем передайте это как параметр, а ваш SP на SharedDatabase всегда будет в контексте этой БД.

+0

Это оба варианта, но не идеальны, поскольку я пытаюсь реорганизовать большой существующий набор таблиц/procs для этого решения. Это потребует больших изменений и потенциального поломки. – RationalGeek

+0

Так почему бы не запустить сохраненные проки непосредственно из двух баз данных, но из SharedDatabase ... то есть вопрос USE Database1 Exec sp_myproc ИЛИ ИСПОЛЬЗОВАНИЯ database2 Exec sp_myproc –

+0

Это не похоже на работу. Proc не видит таблицы в db1 или db2 и с ошибкой типа «не удается найти таблицу». Возможно, я не понимаю вашу идею. Можете ли вы расширить его? – RationalGeek

Смежные вопросы