怎么使用 SQL Server 变更跟踪

已举报 回答 关注

怎么使用 SQL Server 变更跟踪

  • 回答数

    7

  • 浏览数

    2,036

7个回答 默认排序
  • 默认排序
  • 按时间排序

已采纳
如果服务器正在运行 SQL Server 2008,则建议您使用 SQL Server 变更跟踪。如果服务器运行的是其他数据库,请参见如何使用自定义变更跟踪系统。SQL Server 变更跟踪概述本文档中的许多示例都使用一组添加到基表中的列和触发器来处理变更跟踪,使用其他表来跟踪删除操作。有关更多信息,请参见跟踪服务器数据库中的变更。这种类型的跟踪对于非 SQL Server 2008 数据库非常有用。但是,它还是具有以下缺点:在服务器数据库中要求架构变更。架构变更可能会影响其他应用程序,或者可能根本无法实现。对一行中执行的每个变更都会激发触发器。这会影响性能。用于维护正确的行版本和删除的逻辑将变得复杂。如果某一服务器数据库具有长时间运行的事务,则除非这些事务得到正确处理,否则,在同步期间可能会失去数据变更。这可能导致数据不一致。 SQL Server 变更跟踪可解决这些问题,并提供一种简明的方法来跟踪变更。当对某一表启用了变更跟踪时,SQL Server 数据库引擎 将维护有关对表所做变更的信息。然后,应用程序使用相应变更跟踪函数来确定哪些行发生了变更并获取有关这些变更的信息。SQL Server 变更跟踪的主要优点如下:对于使用 Sync Services 的脱机同步方案,您不必创建触发器、时间戳列、其他附加列或附加表。在提交时跟踪变更,而不是在发生 DML 操作时跟踪。函数将返回对表所做的增量变更和版本信息。即使存在重叠和未提交的事务,这些函数也能提供可靠且易于使用的结果。对性能的影响非常小。可以自动清除变更跟踪数据。本主题的其余部分将演示如何在 Sync Services for ADO.NET 应用程序中使用 SQL Server 变更跟踪。有关变更跟踪的更多信息,请参见 SQL Server 2008 联机丛书。将SQL Server 变更跟踪与 Sync Services for ADO.NET 一起使用本节介绍如何启用变更跟踪,以及如何使用变更跟踪查询来确定要下载到客户端的数据变更。本节中的信息介绍如何使用手动创建的命令选择来自服务器的变更。有关如何使用同步适配器生成器为您创建命令的信息,请参见入门:客户端与服务器同步。启用SQL Server 变更跟踪对服务器数据库启用变更跟踪,然后对每个需要跟踪的表启用变更跟踪。下面的代码示例演示一个 Sync Services 示例数据库中的 Sales.Customer 表的架构以及为该表启用变更跟踪所需的代码。每个表都必须有一个主键。主键在所有节点上必须是唯一的,而且不得重复使用:即使删除了某一行,也不得将该行的主键用于其他行。对于分布式环境,标识列通常不是适宜的选择。有关主键的更多信息,请参见为分布式环境选择适宜的主键 (Sync Services)。通过运行以下代码指定的变更跟踪选项包括保留跟踪元数据的时间以及是否自动清除这些元数据。有关跟踪选项的更多信息,请参见 SQL Server 2008 联机丛书中的“变更跟踪”、“ALTER DATABASE”和“ALTER TABLE”主题。 CREATE TABLE SyncSamplesDb_ChangeTracking.Sales.Customer( CustomerId uniqueidentifier NOT NULL PRIMARY KEY DEFAULT NEWID(), CustomerName nvarchar(100) NOT NULL, SalesPerson nvarchar(100) NOT NULL, CustomerType nvarchar(100) NOT NULL) ALTER DATABASE SyncSamplesDb_ChangeTracking SET ALLOW_SNAPSHOT_ISOLATION ON ALTER DATABASE SyncSamplesDb_ChangeTracking SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON) ALTER TABLE SyncSamplesDb_ChangeTracking.Sales.Customer ENABLE CHANGE_TRACKING 注意强烈建议您在查询变更信息时使用快照事务。这有助于确保变更信息的一致性并避免出现与后台清除任务相关的争用情况。有关快照隔离的更多信息,请参见 SQL Server 2008 联机丛书中的“数据库引擎中的隔离级别”。确定要下载到客户端的数据变更启用变更跟踪后,Sync Services 应用程序使用变更跟踪函数和“定位点”来确定要下载的插入、更新和删除。定位点仅仅是用来定义一组要同步的变更的一个时间点。请考虑以下查询:为SelectIncrementalInsertsCommand 属性指定的查询。以下查询从服务器上的 Sales.Customer 表选择要应用于客户端的增量插入: IF @sync_initialized = 0 SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] FROM Sales.Customer LEFT OUTER JOIN CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT ON CT.[CustomerId] = Sales.Customer.[CustomerId] ELSE BEGIN SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] FROM Sales.Customer JOIN CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT ON CT.[CustomerId] = Sales.Customer.[CustomerId] WHERE (CT.SYS_CHANGE_OPERATION = 'I' AND CT.SYS_CHANGE_CREATION_VERSION <= @sync_new_received_anchor) END 如果这是某个客户端的第一个同步会话 (@sync_initialized = 0),则会从 Sales.Customer 基表直接选择架构和所有行。在以后的同步期间,通过执行基表与其变更跟踪表的内部联接来选择新插入的行。变更跟踪表中的元数据由 CHANGETABLE() 函数公开。该函数将基表名称和前一同步操作所存储的变更跟踪版本作为参数。SYS_CHANGE_OPERATION 列定义存储在变更跟踪表行中的变更的类型。注意查询还应检查所需的所有变更是否都已从跟踪表中清除。有关示例,请参见本主题后面的“指定一条从服务器上选择要应用于客户端的增量插入的命令”。为SelectNewAnchorCommand 属性指定的查询。此查询检索一个时间点值。以下查询通过使用 change_tracking_current_version() 函数从服务器中检索新的定位点值。这一内置的 SQL Server 函数返回一个版本整数,它与通过变更跟踪进行跟踪的上次提交的事务相关联。 SELECT @sync_new_received_anchor = change_tracking_current_version() 该整数值存储在客户端数据库中,并且由同步变更的命令使用。在每次同步会话期间,将使用新的定位点值以及来自先前同步会话的上一个定位点值:这意味着将对在这两个作为上下限的定位点值之间做出的变更集进行同步。在某些情况下,应用程序只要求每个客户端上的一部分数据。可以在 WHERE 子句中包括附加的条件,以便筛选数据。有关更多信息,请参见如何筛选行和列。“基于非键列的筛选器”一节中包括与使用 SQL Server 变更跟踪进行筛选有关的重要信息。在同步过程中执行的查询如果是首次同步 Sales.Customer 表,则会执行以下过程:执行新的定位点命令。该命令返回一个整数值,如 372。此值存储在客户端数据库中。该表从未进行过同步。因此,客户端数据库中原本没有存储任何从先前同步操作所得到的定位点值。在这种情况下,Sync Services 使用值 0。Sync Services 执行的查询如下所示: exec sp_executesql N'IF @sync_initialized = 0 SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] FROM Sales.Customer LEFT OUTER JOIN CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT ON CT.[CustomerId] = Sales.Customer.[CustomerId] ELSE BEGIN SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] FROM Sales.Customer JOIN CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT ON CT.[CustomerId] = Sales.Customer.[CustomerId] WHERE (CT.SYS_CHANGE_OPERATION = ''I'' AND CT.SYS_CHANGE_CREATION_VERSION <= @sync_new_received_anchor) END', N'@sync_initialized int, @sync_last_received_anchor bigint, @sync_new_received_anchor bigint', @sync_initialized=0, @sync_last_received_anchor=0, @sync_new_received_anchor=372 在第二次同步会话期间,执行新的定位点命令。自上一会话以来已经插入了一些行。因此,该命令返回值 375。该表以前已进行过同步。因此,Sync Services 可检索先前同步操作所得到的客户端数据库中存储的 372 的定位点值。执行的查询如下所示。该查询只从表中下载在两个定位点值之间插入的行。 exec sp_executesql N'IF @sync_initialized = 0 SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] FROM Sales.Customer LEFT OUTER JOIN CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT ON CT.[CustomerId] = Sales.Customer.[CustomerId] ELSE BEGIN SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] FROM Sales.Customer JOIN CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT ON CT.[CustomerId] = Sales.Customer.[CustomerId] WHERE (CT.SYS_CHANGE_OPERATION = ''I'' AND CT.SYS_CHANGE_CREATION_VERSION <= @sync_new_received_anchor) END', N'@sync_initialized int, @sync_last_received_anchor bigint, @sync_new_received_anchor bigint', @sync_initialized=1, @sync_last_received_anchor=372, @sync_new_received_anchor=375 有关更新和删除命令的示例,请参见本主题后面的完整代码示例。标识执行数据变更的客户端之所以要标识执行数据变更的客户端,主要有两个原因:在仅进行上载的同步和双向同步中为冲突检测和冲突解决提供支持。如果服务器和某个客户端(或多个客户端)可以变更某个给定行,您可能希望标识出变更的执行者。此信息有助于您编写代码,例如,编写确定哪一个变更具有更高的优先级的代码。如果没有此信息,将保留对该行的最近一次变更。在双向同步期间,防止将变更回送给客户端。 Sync Services 首先将变更上载到服务器,然后将变更下载到客户端。如果不跟踪执行变更的客户端的标识,该变更将上载到服务器,然后在同一个同步会话中下载回到该客户端。某些情况下,回送变更是必需的,但是在另一些情况下并非如此。变更跟踪提供一个机制,可以将应用程序数据与变更行时的变更信息一起存储。这些应用程序数据可用于标识正在进行变更的客户端。然后,在您查询变更时可返回进行了变更的客户端的这一标识。SYS_CHANGE_CONTEXT 列可与 ClientId 属性一起使用,以确定每个插入、更新或删除操作是由哪个客户端执行的。在任何表使用除快照同步以外的方法进行第一次同步时,Sync Services 会在客户端上存储一个 GUID 值以标识该客户端。然后将此 ID 传递给 DbServerSyncProvider,以便能够由每个 SyncAdapter 对象的命令使用。可以通过 ClientId 属性以及 @sync_client_id 和@sync_client_id_binary 会话变量获得该 ID 值。请考虑以下 Transact-SQL 查询: IF @sync_initialized = 0 SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] FROM Sales.Customer LEFT OUTER JOIN CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT ON CT.[CustomerId] = Sales.Customer.[CustomerId] WHERE (CT.SYS_CHANGE_CONTEXT IS NULL OR CT.SYS_CHANGE_CONTEXT <> @sync_client_id_binary) ELSE BEGIN SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] FROM Sales.Customer JOIN CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT ON CT.[CustomerId] = Sales.Customer.[CustomerId] WHERE (CT.SYS_CHANGE_OPERATION = 'I' AND CT.SYS_CHANGE_CREATION_VERSION <= @sync_new_received_anchor AND (CT.SYS_CHANGE_CONTEXT IS NULL OR CT.SYS_CHANGE_CONTEXT <> @sync_client_id_binary)); 此查询类似于前面用来跟踪在服务器上所做插入操作的查询。每个 WHERE 子句中的附加语句可确保只下载那些不是由当前进行同步的客户端所做的插入。Sync Services 还允许应用程序通过在服务器上使用一个整数而不是 GUID 值来标识客户端。有关更多信息,请参见如何使用会话变量。若要跟踪哪一客户端进行了在服务器上应用的数据变更,请使用 WITH CHANGE_TRACKING_CONTEXT 子句。在执行 INSERT、UPDATE 或 DELETE 语句前,将 CHANGE_TRACKING_CONTEXT 设置为 @sync_client_id 或@sync_client_id_binary 会话变量的值。此信息存储在变更跟踪表中,以便应用程序可以跟踪变更所处的上下文。对于 Sync Services 来说,这通常是客户端 ID;但是,您可以存储适合 varbinary(128) 列的任何值。 WITH CHANGE_TRACKING_CONTEXT (@sync_client_id_binary) INSERT INTO Sales.Customer (CustomerId, CustomerName, SalesPerson, CustomerType) VALUES (@CustomerId, @CustomerName, @SalesPerson, @CustomerType) SET @sync_row_count = @@rowcount 了解和运行示例应用程序本节包含配置和执行同步所需的应用程序代码。只通过阅读示例代码,就可以学习到很多相关知识。但是,运行示例并查看其运行情况则更加直观。在运行代码前,请确保安装了以下产品: Sync Services 该应用程序需要参考 Microsoft.Synchronization.Data.dll、Microsoft.Synchronization.dll、Microsoft.Synchronization.Data.Server.dll 和 Microsoft.Synchronization.Data.SqlServerCe.dll。 SQL Server 2008 示例代码在连接字符串中使用 localhost。若要使用远程服务器,请将 localhost 变更为适当的服务器名称。Sync Services 示例数据库。有关更多信息,请参见用于Sync Services 帮助主题的安装脚本。如果您曾经阅读过用于客户端与服务器同步的体系结构和类主题,应该已经对该应用程序中使用的主要类有所了解。该应用程序由以下类组成:SampleSyncAgent此类派生自 SyncAgent。SampleServerSyncProvider。此类派生自 DbServerSyncProvider 并包含 SyncAdapter 和一组查询变更跟踪表的命令。SampleClientSyncProvider此类派生自 SqlCeClientSyncProvider 并包含 SyncTable。SampleStats此类使用 SyncAgent 返回的统计信息。Program。此类设置同步并调用 Utility 类的方法。Utility. 此类负责处理所有不与同步直接相关的功能,例如保存连接字符串信息以及更改服务器和客户端数据库等。有关更多信息,请参见 用于Sync Services 帮助主题的 Utility 类。API 的要点在您查看完整代码示例之前,建议您首先查看以下示例。这些示例阐释在本应用程序中使用的 API 的若干要点。所演示的所有示例代码都包含在 SampleServerSyncProvider 类中。除了在本节中演示的命令外,该完整代码示例还包含可将插入应用于服务器的命令以及选择和应用删除的命令。第一个示例直接应用于 DbServerSyncProvider 属性SelectNewAnchorCommand。其他示例应用于 Sales.Customer 表的SyncAdapter 对象。从服务器中检索新的定位点值以下代码示例指定从服务器中检索新定位点值的命令。SyncSession 类包含几个可在同步命令中使用的字符串常量。SyncNewReceivedAnchor 是这些常量之一。此外,还可以在查询中直接使用 @sync_new_received_anchor 文本。C#VB SqlCommand selectNewAnchorCommand = new SqlCommand(); string newAnchorVariable = "@" + SyncSession.SyncNewReceivedAnchor; selectNewAnchorCommand.CommandText = "SELECT " + newAnchorVariable + " = change_tracking_current_version()"; selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.BigInt); selectNewAnchorCommand.Parameters[newAnchorVariable].Direction = ParameterDirection.Output; selectNewAnchorCommand.Connection = serverConn; this.SelectNewAnchorCommand = selectNewAnchorCommand; 指定一条从服务器上选择要应用于客户端的增量插入的命令下面的代码示例指定一条从服务器上选择要应用于客户端的增量插入的命令。用于增量变更的所有查询都将检查所需的变更是否已从变更跟踪表中清除。此检查从以下子句开始,并且在已清除变更后将引发错误:IF CHANGE_TRACKING_MIN_VALID_VERSION (object_id (@sync_table_name)) > @sync_last_received_anchorC#VB SqlCommand customerIncrInserts = new SqlCommand(); customerIncrInserts.CommandText = "IF @sync_initialized = 0 " + "SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] " + "FROM Sales.Customer LEFT OUTER JOIN " + "CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT " + "ON CT.[CustomerId] = Sales.Customer.[CustomerId] " + "WHERE (CT.SYS_CHANGE_CONTEXT IS NULL OR CT.SYS_CHANGE_CONTEXT <> @sync_client_id_binary) " + "ELSE " + "BEGIN " + "SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] " + "FROM Sales.Customer JOIN CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT " + "ON CT.[CustomerId] = Sales.Customer.[CustomerId] " + "WHERE (CT.SYS_CHANGE_OPERATION = 'I' AND CT.SYS_CHANGE_CREATION_VERSION " + "<= @sync_new_received_anchor " + "AND (CT.SYS_CHANGE_CONTEXT IS NULL OR CT.SYS_CHANGE_CONTEXT <> @sync_client_id_binary)); " + "IF CHANGE_TRACKING_MIN_VALID_VERSION(object_id(@sync_table_name)) " + "> @sync_last_received_anchor " + "RAISERROR (N'SQL Server Change Tracking has cleaned up tracking information for table ''%s''. " + "To recover from this error, the client must reinitialize its local database and try again' " + ",16,3,@sync_table_name) " + "END"; customerIncrInserts.Parameters.Add("@" + SyncSession.SyncInitialized, SqlDbType.Int); customerIncrInserts.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.BigInt); customerIncrInserts.Parameters.Add("@" + SyncSession.SyncClientIdBinary, SqlDbType.Binary); customerIncrInserts.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.BigInt); customerIncrInserts.Parameters.Add("@" + SyncSession.SyncTableName, SqlDbType.NVarChar); customerIncrInserts.Connection = serverConn; customerSyncAdapter.SelectIncrementalInsertsCommand = customerIncrInserts; 指定一条从服务器上选择要应用于客户端的增量更新的命令下面的代码示例指定一条从服务器上选择要应用于客户端的增量更新的命令。C#VB SqlCommand customerIncrUpdates = new SqlCommand(); customerIncrUpdates.CommandText = "IF @sync_initialized > 0 " + "BEGIN " + "SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType] " + "FROM Sales.Customer JOIN " + "CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT " + "ON CT.[CustomerId] = Sales.Customer.[CustomerId] " + "WHERE (CT.SYS_CHANGE_OPERATION = 'U' AND CT.SYS_CHANGE_VERSION " + "<= @sync_new_received_anchor " + "AND (CT.SYS_CHANGE_CONTEXT IS NULL OR CT.SYS_CHANGE_CONTEXT <> @sync_client_id_binary)); " + "IF CHANGE_TRACKING_MIN_VALID_VERSION(object_id(@sync_table_name)) " + "> @sync_last_received_anchor " + "RAISERROR (N'SQL Server Change Tracking has cleaned up tracking information for table ''%s''. " + "To recover from this error, the client must reinitialize its local database and try again'" + ",16,3,@sync_table_name) " + "END"; customerIncrUpdates.Parameters.Add("@" + SyncSession.SyncInitialized, SqlDbType.Int); customerIncrUpdates.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.BigInt); customerIncrUpdates.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.BigInt); customerIncrUpdates.Parameters.Add("@" + SyncSession.SyncClientIdBinary, SqlDbType.Binary); customerIncrUpdates.Parameters.Add("@" + SyncSession.SyncTableName, SqlDbType.NVarChar); customerIncrUpdates.Connection = serverConn; customerSyncAdapter.SelectIncrementalUpdatesCommand = customerIncrUpdates; 指定一条将增量更新从客户端应用于服务器的命令在以下代码示例中,UPDATE 语句更新基表,并返回受影响的行的计数。如果行计数为 0,则表示发生了错误或冲突。有关更多信息,请参见如何处理数据冲突和错误。C#VB SqlCommand customerUpdates = new SqlCommand(); customerUpdates.CommandText = ";WITH CHANGE_TRACKING_CONTEXT (@sync_client_id_binary) " + "UPDATE Sales.Customer " + "SET [CustomerName] = @CustomerName, [SalesPerson] = @SalesPerson, [CustomerType] = @CustomerType " + "FROM Sales.Customer " + "JOIN CHANGETABLE(VERSION Sales.Customer, ([CustomerId]), (@CustomerId)) CT " + "ON CT.[CustomerId] = Sales.Customer.[CustomerId] " + "WHERE (@sync_force_write = 1 " + "OR CT.SYS_CHANGE_VERSION IS NULL OR CT.SYS_CHANGE_VERSION <= @sync_last_received_anchor " + "OR (CT.SYS_CHANGE_CONTEXT IS NOT NULL AND CT.SYS_CHANGE_CONTEXT = @sync_client_id_binary)) " + "SET @sync_row_count = @@rowcount; " + "IF CHANGE_TRACKING_MIN_VALID_VERSION(object_id(@sync_table_name)) > @sync_last_received_anchor " + "RAISERROR (N'SQL Server Change Tracking has cleaned up tracking information for table ''%s''. " + "To recover from this error, the client must reinitialize its local database and try again'" + ",16,3,@sync_table_name)"; customerUpdates.Parameters.Add("@" + SyncSession.SyncClientIdBinary, SqlDbType.Binary); customerUpdates.Parameters.Add("@CustomerName", SqlDbType.NVarChar); customerUpdates.Parameters.Add("@SalesPerson", SqlDbType.NVarChar); customerUpdates.Parameters.Add("@CustomerType", SqlDbType.NVarChar); customerUpdates.Parameters.Add("@CustomerId", SqlDbType.UniqueIdentifier); customerUpdates.Parameters.Add("@" + SyncSession.SyncForceWrite, SqlDbType.Bit); customerUpdates.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.BigInt); customerUpdates.Parameters.Add("@" + SyncSession.SyncRowCount, SqlDbType.Int); customerUpdates.Parameters["@" + SyncSession.SyncRowCount].Direction = ParameterDirection.Output; customerUpdates.Parameters.Add("@" + SyncSession.SyncTableName, SqlDbType.NVarChar); customerUpdates.Connection = serverConn; customerSyncAdapter.UpdateCommand = customerUpdates; 选择冲突行下面的命令从服务器数据库中选择冲突行(如果这些行仍存在于基表中)。C#VB SqlCommand customerUpdateConflicts = new SqlCommand(); customerUpdateConflicts.CommandText = "SELECT Sales.Customer.[CustomerId], [CustomerName], [SalesPerson], [CustomerType], " + "CT.SYS_CHANGE_CONTEXT, CT.SYS_CHANGE_VERSION " + "FROM Sales.Customer JOIN CHANGETABLE(VERSION Sales.Customer, ([CustomerId]), (@CustomerId)) CT " + "ON CT.[CustomerId] = Sales.Customer.[CustomerId]"; customerUpdateConflicts.Parameters.Add("@CustomerId", SqlDbType.UniqueIdentifier); customerUpdateConflicts.Connection = serverConn; customerSyncAdapter.SelectConflictUpdatedRowsCommand = customerUpdateConflicts; 下面的命令从服务器数据库中选择冲突行(如果这些行已从基表中删除)。C#VB SqlCommand customerDeleteConflicts = new SqlCommand(); customerDeleteConflicts.CommandText = "SELECT CT.[CustomerId], " + "CT.SYS_CHANGE_CONTEXT, CT.SYS_CHANGE_VERSION " + "FROM CHANGETABLE(CHANGES Sales.Customer, @sync_last_received_anchor) CT " + "WHERE (CT.[CustomerId] = @CustomerId AND CT.SYS_CHANGE_OPERATION = 'D')"; customerDeleteConflicts.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.BigInt); customerDeleteConflicts.Parameters.Add("@CustomerId", SqlDbType.UniqueIdentifier); customerDeleteConflicts.Connection = serverConn; customerSyncAdapter.SelectConflictDeletedRowsCommand = customerDeleteConflicts; 有关如何处理数据冲突的更多信息,请参见如何处理数据冲突和错误。完整的代码示例下面的完整代码示例包括了上面介绍的代码示例以及用于执行同步的其他代码。C#VBusing System; using System.IO; using System.Text; using System.Data; using System.Data.SqlC
取消 评论
最新的版本的sql,好象没有主键是工作不了的。
你这个情况貌似数据库已经有重复数据了,没有办法设置成主键,你得回头去看一下数据库,
是不是你设置的主键已经有重复值了。
取消 评论
SQL Server身份验证:即只能是使用这个数据库的人才能进去。
windows身份验证:即只要进入操作系统就能使用该数据库。
登陆名和密码:跟你进入XP系统要求输入用户名和密码是一样的。
登录名为sa,密码为你安装SQL Server 2005时自己所设的密码,如果你没设,那就是空。
取消 评论
数据库服务启动了没?
没有的话,先用SQL Server Configuration Manager打开数据库服务,然后在连接一次试试
取消 评论
内存使用率是越高越好的。如果居高不下,就有可能是内存不足。
不合理的SQL语句和设计也会不合理占用内存。这就是要具体问题具体优化了。
取消 评论
这个需要先建一个实例,没有实例是无法使用的。
取消 评论
若若问一句,你把混合登陆模式开启了么
取消 评论
ZOL问答 > 相机 > 尼康相机 > 其他分类 > 怎么使用 SQL Server 变更跟踪

举报

感谢您为社区的和谐贡献力量请选择举报类型

举报成功

经过核实后将会做出处理
感谢您为社区和谐做出贡献

提示

确定要取消此次报名,退出该活动?