我正在尝试编写一个数据库脚本(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)作为我的变量类型还是别的什么?
由于
答案 0 :(得分:2)
有一种更好的方法可以做到这一点,但你可能在你的例子中尝试做的是所谓的动态SQL,你将语句视为一个字符串并执行它。这将是第2节: http://www.mssqltips.com/tip.asp?tip=1160
动态SQL有一些主要缺点。您会在该文章中看到其他几种可能更好的方法。
答案 1 :(得分:2)
如果要执行动态生成的查询,则必须使用sp_ExecuteSQL
HTH
答案 2 :(得分:2)
对于nvarchar(50) - 你最好使用sysname。这是SQL Server中的同义词(对于nvarchar(128)),表示对象标识符的最大长度。
答案 3 :(得分:1)
查看http://msdn.microsoft.com/en-us/library/ms188001.aspx - sp_executesql
获取一个字符串参数并执行该字符串中的sql。因此,您需要将@SERVER_FROM和其他参数与INSERT INTO部分连接起来以生成整个sql语句,然后传递给sp_executesql。
nvarchar(50)没问题,除非您的服务器/数据库名称长于:)
答案 4 :(得分:1)
您可以通过将所有信息连接在一起来创建select语句,然后使用sp_executesql 这样:
sp_executesql 'INSERT INTO ' + @SERVER_TO + '.' + @DATABASE_TO +
'.dbo.TableName SELECT * FROM ' + @SERVER_FROM + '.' +
@DATABASE_FROM+'.dbo.TableName'
答案 5 :(得分: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)