0

我有一个表,我使用SqlCommand变量从该表中读取,ExecuteReader在其上执行我正在交互以获取每一行的返回SqlDataReader对象,从该表中我对字符串执行操作以在插入新数据库时使用SqlCommand变量并执行ExecuteNonQuery().

我的问题是是否有更优雅/更有效的方法来做到这一点?就像在一个命令中获取所有行并一次插入它们或其他任何比当前流更好的东西。

更新 一件重要的事情是这些表位于不同服务器上的不同数据库中。

4

4 回答 4

2

我建议:一步一步尝试。

INSERT INTO yourDataBase1.yourTable1 VALUES (Column1, Column2, ...)
SELECT Column1, Column2, ... FROM yourDataBase2.yourTable1

好处:

  • 通过以太网减少流量
  • 与其他解决方案(例如存储过程)相比,速度更快

我会在您的 C# 应用程序(传输/回滚)中基于事务执行此操作。因此,如果出现问题,它不会只插入一半的行。

于 2013-07-15T20:56:15.610 回答
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
于 2013-07-15T20:39:53.393 回答
0

如果操作是您需要 C# .NET 的东西,那么您有两个选择

1) 使用以下语法构建和插入多行:
values (), ()
您可以在单个语句中插入多行 - 这将减少
每次插入的总值小于 1000 的最佳方式

2)使用TVP(表值参数)

您可以在 TSQL 中执行操作,然后只需插入。
或者使用 CLR,以便您可以在插入中使用 C#。

通过链接服务器,您可以遍历服务器。
您只需在插入/选择中使用 4 部分名称。

于 2013-07-15T20:43:17.883 回答
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
于 2013-07-16T11:55:56.843 回答