在做站点复制的时候,发现有时候会出现“System.Data.SqlClient.SqlException: 违反了 PRIMARY KEY 约束 'PK__#ExportObjects____52593CB8'。不能在对象 'dbo.#ExportObjects' 中插入重复键。”的错误:

message: System.Data.SqlClient.SqlException: 违反了 PRIMARY KEY 约束 'PK__#ExportObjects____52593CB8'。不能在对象 'dbo.#ExportObjects' 中插入重复键。
语句已终止。
   在 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
   在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   ……(略去)

我的版本为MOSS 2007 SP1,在Technet上搜索该错误,发现有一个讨论比较多的帖子:http://social.technet.microsoft.com/forums/en-US/sharepointadmin/thread/2e13998b-5cec-4201-b1b4-03b0d7b701c1/,最终的结论是这是WSS的一个Bug,有一个Hotfix可以解决(KB950279),大家可以通过如下地址下载该补丁:http://support.microsoft.com/kb/950279,相信遇到这个问题的朋友大部分可以解决该问题了。

但是遗憾的是,我的问题仍然没有解决,甚至将WSS升级到SP2仍然无济于事。

经过仔细的分析研究,终于找到了问题所在:

微软在升级到SP1的时候,由于版本规则产生了变化,因此对SPListItem的导出做了调整,而导出是先放入到临时表里面“#ExportObjects”,微软却没有及时更新Content Deployment模块,致使当一个SPListItem包含多个版本的时候,由于各个版本guid相同,在用存储过程“proc_DeplAddListItem”插入临时表的时候出错,于是通过Hotfix:950279更新了该存储过程,但是遗憾的是,950279却没有更新存储过程“proc_DeplAddFolder”,即没有对SPFolder做调整,因此,对于由SPFolder继承来的内容类型,如果有多个版本的话,就会产生上面的错误。

上面是我的个人判断,实际测试时,当folder类型的对象只有一个版本的时候,导出成功,当包含多个版本的时候,导出出错,因此证实了我的推断基本上是正确的。希望微软能及时更新此问题。

但是我没有时间等微软发布新的Hotfix,而且也许大多数应用不会用到SPFolder对象的版本,问题还得自己解决,解决的办法我曾想过在导出的对象上加上属性:

“settings.IncludeVersions = SPIncludeVersions.LastMajor;”

发现也不行,因为对SPFolder继承来的Content type根本不起作用,于是只好更改MOSS系统本身提供的存储过程:proc_DeplAddFolder

解决办法:

打开存储过程(数据库/相应的数据库实例/可编程性/系统存储过程):
找到proc_DeplAddFolder,将其中的:
SELECT
        Docs.Id,
        CASE
            WHEN Docs.DocLibRowId IS NOT NULL THEN 6
            ELSE 2
        END,
        0,
        Docs.DirName,
        Docs.LeafName,
        Docs.ParentId,
        Docs.WebId,
        @IncludeDescendants,
        @IsLink,
改为:

SELECT DISTINCT
        Docs.Id,
        CASE
            WHEN Docs.DocLibRowId IS NOT NULL THEN 6
            ELSE 2
        END,
        0,
        Docs.DirName,
        Docs.LeafName,
        Docs.ParentId,
        Docs.WebId,
        @IncludeDescendants,
        @IsLink,

即在Select后面加了一个:DISTINCT(加黑斜体字),就可以了,经过测试成功!

由于能力和时间所限,没有再深入研究该存储过程,如果能有更完善的解决办法,希望告知。

posted on 2009-12-22 14:27  重金属  阅读(3685)  评论(0编辑  收藏  举报