Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 从存储过程复制表的数据_Sql_Sql Server 2008_Stored Procedures_Ssms - Fatal编程技术网

Sql 从存储过程复制表的数据

Sql 从存储过程复制表的数据,sql,sql-server-2008,stored-procedures,ssms,Sql,Sql Server 2008,Stored Procedures,Ssms,我正在学习如何使用SQL和存储过程。我知道语法不正确: 使用存储过程将数据从一个表复制到另一个数据库上的另一个表中。问题是我不知道要复制到哪个表或哪个数据库。我希望它使用参数,而不是专门指定列 我有两个数据库Master_db和Master_copy,每个数据库上都有相同的表结构 我想在Master_db中快速选择一个表,并将该表的数据复制到同名的Master_copy表中。我想出了这样的办法: USE Master_DB CREATE PROCEDURE TransferData DEFINE

我正在学习如何使用SQL和存储过程。我知道语法不正确:

使用存储过程将数据从一个表复制到另一个数据库上的另一个表中。问题是我不知道要复制到哪个表或哪个数据库。我希望它使用参数,而不是专门指定列

我有两个数据库Master_db和Master_copy,每个数据库上都有相同的表结构

我想在Master_db中快速选择一个表,并将该表的数据复制到同名的Master_copy表中。我想出了这样的办法:

USE Master_DB
CREATE PROCEDURE TransferData
DEFINE @tableFrom, @tableTo, @databaseTo;

INSERT INTO @databaseTo.dbo.@databaseTo
SELECT * FROM Master_DB.dbo.@tableFrom
GO;
我能得到的最接近的就是这个。现在的问题是,我有一个Timestamp列,它呈现了一个错误:

无法在时间戳列中插入显式值。在列列表中使用INSERT可排除timestamp列,或在timestamp列中插入默认值

USE Kenneth_Integration
GO
CREATE PROCEDURE TransferData
  @table  SYSNAME
  ,@databaseTo SYSNAME
AS
DECLARE @sql NVARCHAR(MAX)

SET @sql = 'DELETE FROM ' + @databaseTo + '..' + @table + ' set identity_insert ' + @databaseTo + '.dbo.' + @table + 
    ' on INSERT INTO ' + @databaseTo + '.dbo.' + @table + ' SELECT * FROM Kenneth_Integration.dbo.' + @table

EXEC sp_executesql @sql
GO

如何使用此SP绕过此错误?

我的建议是编写返回表的函数 然后使用insert select语句

过程和函数之间的差异超出了您无法编写的范围 选择程序,但 你可以写
SQL查询中的select function(选择函数)

对象名称不能以您尝试的方式进行参数化

要使其正常工作,您需要使用动态SQL:

USE Master_DB
CREATE PROCEDURE TransferData
 @tableFrom   SYSNAME
 ,@tableTo    SYSNAME
 ,@databaseTo SYSNAME
AS
DECLARE @sql NVARCHAR(MAX)
SET @sql = 'INSERT INTO ' + @databaseTo+ '.dbo.' + @tableTo + '
            SELECT * FROM Master_DB.dbo.' + @tableFrom

EXEC sp_executesql @sql
GO;

只有动态SQL允许变量作为表名。例如:

create procedure dbo.TransferData(
    @src varchar(50),
    @dest varchar(50))
as
declare @query varchar(500)
set @query = 'INSERT INTO ' + @src +
    'SELECT * FROM ' + @dest
exec @query
go

我同意@EdHarper的观点,构建一个字符串然后运行sp_executesql可能是最好的答案

在前面的回答中,我没有看到两件事:

1您以前可能已经将数据复制到Master_copy数据库表中,因此您可能需要在开始复制操作之前删除目标表中的数据

2例如,如果由于使用相同的Sql脚本生成Master_db和Master_copy表而在Master_copy表中有任何标识列,则需要确保可以覆盖标识值,这可以通过命令完成

因此,作为一种替代方法,没有必要再重复回答另一个问题,因为您知道数据库名称,您可以简单地对这种方法进行反规范化,并为每个表编写一个简单的存储过程

假设您有一个名为“person”的表,您可以写:

create procedure TransferDataPerson 
as

delete from Master_copy..Person

set identity_insert Master_copy..Person on

insert into Master_copy..Person
select * from Master_db..Person

。。。每个表都是如此。

好的,但这对我帮助不大,因为我有SQL语言问题,我认为语法是非常错误的。我甚至不知道这是否可能?您是否考虑过,如果要复制到一个可能已经有一些要复制的数据的表中,该怎么办?身份栏也可能是一个问题。我已经考虑了您的观点,并将它们添加到查询中。谢谢,回答得很好!这个问题现在被添加到本页的答案中。动态SQL对我来说是新的,感谢您为我指明了正确的方向。我相信你的提问有一个错误。但是你的回答是正确的!错误的@databaseTo+'.dbo'+@databaseTo@Niike2-更正。我从您的原始帖子中复制了错误。我建议在执行类似操作时,在对象名称周围使用QuoteName函数。