我有一个表,我使用SqlCommand
变量读取它,在其上执行ExecuteReader
和返回的SqlDataReader
对象,我正在计算每一行,我从哪里开始对使用SqlCommand
变量并执行ExecuteNonQuery()
的新数据库中的插入执行的字符串的操作。
我的问题是,是否有更优雅/有效的方法来做到这一点?比如在一个命令中获取所有行并将它们全部插入所有行或其他任何比当前流更好的行。
更新 一个重要的事情是表位于不同服务器上的不同数据库中。
答案 0 :(得分:2)
我建议:一步完成。
INSERT INTO yourDataBase1.yourTable1 VALUES (Column1, Column2, ...)
SELECT Column1, Column2, ... FROM yourDataBase2.yourTable1
优点:
我会在你的C#应用程序(传输/回滚)中执行此事务。因此,如果出现问题,它不会只插入一半的行。
答案 1 :(得分:1)
您可以编写一个类似
的存储过程或SqlCommand
INSERT INTO DB1.dbo.TestTable(FirstName, LastName)
SELECT RemoteTable.FirstName, RemoteTable.LastName FROM
OPENROWSET('SQLOLEDB',
'Server=x.x.x.x;Trusted_Connection=yes;user_id=xxxx;password=xxxx',
'SELECT FirstName, LastName FROM DB2.dbo.TestTable' ) as RemoteTable
答案 2 :(得分:0)
如果操作是您需要C#.NET的话,那么您有两个选项
1)使用以下语法构建并插入多行:
values(),()
你可以在一个语句中插入多行 - 这样可以减少它的繁琐
最好保持每个插入的总值小于1000
2)使用TVP(表值参数)
您可以在TSQL中执行操作,然后只需插入一个插件 或者使用CLR,这样你就可以在插入中使用C#。
通过链接服务器,您可以遍历服务器 您只需在插入/选择中使用4部分名称。
答案 3 :(得分:0)
我要发布两个答案的混合Jay Patel是最好的方法,因为你想使用不同的服务器和数据库。
但将它包装在try catch和一个事务中将是最好的主意,因此我将采用Jay Patel的方法并将其包装,以便因失败而无法进行故障转移。
BEGIN TRAN -- START THE TRANSACTION BUT DONT PHSICALLY PUT THE ROWS IN THE DATABASE UNTIL COMMIT
BEGIN TRY
INSERT INTO DB1.dbo.TestTable(FirstName, LastName)
SELECT RemoteTable.FirstName, RemoteTable.LastName FROM
OPENROWSET('SQLOLEDB',
'Server=x.x.x.x;Trusted_Connection=yes;user_id=xxxx;password=xxxx',
'SELECT FirstName, LastName FROM DB2.dbo.TestTable' ) as RemoteTable
END TRY
BEGIN CATCH
ROLLBACK -- IF THE INSERT FAILS DONT INSERT ANYROWS INTO THE DATABASE
END CATCH
COMMIT --USED FOR COMMITING THE ROWS TO THE DATABASE THEY ARE NOT ACTUALLY IN THE DATABASE UNTIL THIS HAS BEEN COMMITED