2010-04-09 2 views
3

Я пытаюсь написать сценарий базы данных (SQL Server 2008), который скопирует информацию из таблиц базы данных на одном сервере в соответствующие таблицы в другой базе данных на другом сервере.Использование значений параметров В SQL-заявлении

Я прочитал, что правильный способ сделать это состоит в использовании SQL заявления, в формате, аналогичном следующий:

INSERT INTO <linked_server>.<database>.<owner>.<table_name> SELECT * FROM <linked_server>.<database>.<owner>.<table_name> 

Как будет несколько таблиц копируются, я хотел бы объявить переменные в верхней части сценария, чтобы пользователь мог указать имена каждого сервера и базы данных, которые будут использоваться. Затем они могут использоваться во всем скрипте. Однако я не уверен, как использовать значения переменных в действительных операциях SQL. То, что я хочу достичь, это что-то вроде следующего:

DECLARE @SERVER_FROM AS NVARCHAR(50) = 'ServerFrom' 
DECLARE @DATABASE_FROM AS NVARCHAR(50) = 'DatabaseTo' 

DECLARE @SERVER_TO AS NVARCHAR(50) = 'ServerTo' 
DECLARE @DATABASE_TO AS NVARCHAR(50) = 'DatabaseTo' 

INSERT INTO @[email protected]_TO.dbo.TableName SELECT * FROM @[email protected]_FROM.dbo.TableName 
... 

Как следует использовать @ переменные в этом коде, для того, чтобы правильно работать?

Кроме того, как вы думаете, мой метод выше правильно для того, чего я пытаюсь достичь, и должен ли я использовать NVARCHAR (50) как мой тип переменной или что-то еще?

Благодаря

ответ

1

имеют вид на http://msdn.microsoft.com/en-us/library/ms188001.aspx - sp_executesql принимает параметр, который является строкой, и выполняет SQL в этой строке. поэтому вам нужно будет конкатенировать @SERVER_FROM и другие параметры с частью INSERT INTO, чтобы сделать весь оператор sql, а затем перейти к sp_executesql.

NVARCHAR (50) в порядке, если ваши имена серверов/баз данных не дольше, чем это :)

1

Вы можете создать оператор выбора путем конкатенации всю информацию вместе, а затем использовать sp_executesql так:

sp_executesql 'INSERT INTO ' + @SERVER_TO + '.' + @DATABASE_TO + 
'.dbo.TableName SELECT * FROM ' + @SERVER_FROM + '.' + 
@DATABASE_FROM+'.dbo.TableName' 
2

Возможно, это лучший способ сделать это, но то, что вы, вероятно, пытаетесь сделать в своем примере, - это то, что называется динамическим SQL, где вы обрабатываете оператор как строку и выполняете ее. Это будет раздел № 2 здесь: http://www.mssqltips.com/tip.asp?tip=1160

Есть некоторые основные недостатки динамического SQL. Вы видите пару других подходов, которые могут быть лучше в этой статье.

2

Если вы хотите выполнить динамически сгенерированный запрос, то вы должны использовать sp_ExecuteSQL

HTH

2

Для NVARCHAR (50) - вы бы лучше с помощью sysname. Это синоним в SQL Server (для nvarchar (128)) и представляет максимальную длину идентификатора объекта.

0

Мне нравится делать шаблоны для динамических SQL-подобных вещей - намного проще поддерживать сложные инструкции, а также иногда проще обрабатывать вложенные кавычки - и, безусловно, проще, когда условия нужно повторять в нескольких местах (например, в списках столбцов) :

DECLARE @sql AS nvarchar(max); 
SET @sql = 'INSERT INTO {@SERVER_TO}.{@DATABASE_TO}.dbo.TableName 
SELECT * 
FROM {@SERVER_FROM}.{@DATABASE_FROM}.dbo.TableName' 

SET @sql = REPLACE(@sql, '{@SERVER_TO}', QUOTENAME(@SERVER_TO)) 
SET @sql = REPLACE(@sql, '{@DATABASE_TO}', QUOTENAME(@DATABASE_TO)) 
SET @sql = REPLACE(@sql, '{@SERVER_FROM}', QUOTENAME(@SERVER_FROM)) 
SET @sql = REPLACE(@sql, '{@DATABASE_FROM}', QUOTENAME(@DATABASE_FROM)) 

EXEC(@sql) 
Смежные вопросы