Использование значений параметров в выражении SQL - PullRequest
3 голосов
/ 09 апреля 2010

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

Я прочитал, что правильный способ сделать это - использовать оператор 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 @SERVER_TO.@DATABASE_TO.dbo.TableName SELECT * FROM @SERVER_FROM.@DATABASE_FROM.dbo.TableName
...

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

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

Спасибо

Ответы [ 6 ]

2 голосов
/ 09 апреля 2010

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

2 голосов
/ 09 апреля 2010

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

НТН

2 голосов
/ 09 апреля 2010

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

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

1 голос
/ 09 апреля 2010

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

sp_executesql 'INSERT INTO ' + @SERVER_TO + '.' + @DATABASE_TO + 
'.dbo.TableName SELECT * FROM ' +  @SERVER_FROM + '.' + 
@DATABASE_FROM+'.dbo.TableName'
1 голос
/ 09 апреля 2010

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

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

0 голосов
/ 09 апреля 2010

Мне нравится создавать шаблоны для таких вещей, как динамический 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...