解决此唯一主键问题的一个有效方法是为数据库的每个用户指派一个可在需要时使用的主键值池。例如,您可以为每个销售代表指派 100 个新标识值。这样,每个销售代表就可以为新客户任意指派自己池中的值。
在统一数据库和每个远程数据库中添加一个新表来保存新的主键池。除了用于保存唯一值的列,这些表中还应包含一个用户名列,以标识哪些用户已被授予指派该值的权限。
编写存储过程以确保为每个用户都指派了足够多的新标识值。为那些插入许多新条目或不经常执行同步的远程用户指派更多的新值。
编写 download_cursor 脚本,以选择指派给每个用户的新值,并将它们下载到远程数据库中。
修改将使用远程数据库的应用程序,以便在用户插入新行时应用程序使用池中的其中一个值。然后,应用程序必须从池中删除该值,以确保不会再次使用它。
编写上载脚本。然后,MobiLink 服务器从统一值池中删除那些用户已从远程数据库中自己的值池中删除的行。
编写 end_upload 脚本以调用用来维护值池的存储过程。这样做将向用户的池中添加更多的值以代替在上载过程中删除的值。
该示例应用程序允许远程用户添加客户。应确保每个新行都有唯一的主键值,而且在输入数据时所有远程数据库的连接都必须是断开的。
ULCustomerIDPool 包含可由各远程数据库使用的主键值的列表。另外,ULCustomerIDPool_maintain 存储过程在值用完时将池加满。维护过程由表级 end_upload 脚本调用,而各个远程数据库上的池由 upload_insert 和 download_cursor 脚本维护。
统一数据库中的 ULCustomerIDPool 表用于保存新客户标识号池。它与 ULCustomer 表之间不存在直接链接。
ULCustomerIDPool_maintain 过程将更新统一数据库中的 ULCustomerIDPool 表。以下示例代码适用于 SQL Anywhere 统一数据库。
CREATE PROCEDURE ULCustomerIDPool_maintain ( IN syncuser_id INTEGER ) BEGIN DECLARE pool_count INTEGER; -- Determine how may ids to add to the pool SELECT COUNT(*) INTO pool_count FROM ULCustomerIDPool WHERE pool_emp_id = syncuser_id; -- Top up the pool with new ids WHILE pool_count < 20 LOOP INSERT INTO ULCustomerIDPool ( pool_emp_id ) VALUES ( syncuser_id ); SET pool_count = pool_count + 1; END LOOP; END |
此过程对目前指派给当前用户的号码进行计数并插入新行,以确保此用户具有足够的客户标识号。
此过程由 ULCustomerIDPool 表的 end_upload 表脚本在上载结束时调用。该脚本如下所示:
CALL ULCustomerIDPool_maintain( {ml s.username} ) |
ULCustomerIDPool 表的 download_cursor 脚本将新的标识号下载到远程数据库中。
SELECT pool_cust_id FROM ULCustomerIDPool WHERE pool_emp_id = {ml s.username} AND last_modified >= {ml s.last_table_download} |
要插入新客户,使用远程数据库的应用程序必须从池中选择一个未使用的标识号,并从池中删除此编号,然后使用此标识号插入新客户的信息。以下 UltraLite 应用程序的嵌入式 SQL 函数将从池中检索一个新客户号。
bool CDemoDB::GetNextCustomerID( void ) /*************************************/ { short ind; EXEC SQL SELECT min( pool_cust_id ) INTO :m_CustID:ind FROM ULCustomerIDPool; if( ind < 0 ) { return false; } EXEC SQL DELETE FROM ULCustomerIDPool WHERE pool_cust_id = :m_CustID; return true; } |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |