Content databases contain orphaned items, Violation of PRIMARY KEY (SharePoint)
A volte in SharePoint può comparire il seguente errore
si può verificare quali sono gli elementi che danno errore, ad esempio:
normalmente si può risolvere attraverso la central administration o con Powershell
eseguendo i repair
può capitare che l'esecuzione da PowerShell dia questo errore (dalla Central Administration non c'è nessuna segnalazione)
Quando compare questo errore normalmente l'item è visibile da SharePoint ma non è possibile editarlo o elencarne le permission.
Per sistemarlo bisogna intervenire sul Database per recuperare lo scopeId orfano e l'id del documento.
Poi tramite la store proc_SecResetItemPerm si può resettare le permission in modo da ereditare dal parent.
Questo è le script T-SQL per eseguire la riparazione va impostato il parametro docName con il percorso ritornato nell'errore:
Content databases contain orphaned items.
verificando con il comando PowerShell Get-SPContentDatabase e il suo metodo RepairPowerShell
$db = Get-SPContentDatabase SP_Content_Portal
$db.Repair($false)
XML
<OrphanedObjects Count="1">
<Orphan Type="SecurityScope"
SiteId="{8CBCD65F-940C-49D7-A4E0-073257BC91A2}"
Name="HelpDesk/Lists/servicerequests/16812_.000"
InRecycleBin="No" />
</OrphanedObjects>
eseguendo i repair
PowerShell
$db.Repair($true)
Exception calling "Repair" with "1" argument(s): "Violation of PRIMARY KEY constraint 'Perms_PK'. Cannot insert duplicate key in object 'dbo.Perms'.
The duplicate key value is (8cbcd65f-940c-49d7-a4e0-073257bc91a2, 0x, HelpDesk/Lists/servicerequests/16812_.000).
The statement has been terminated."
anche con stsadm ottengo lo stesso messaggioThe duplicate key value is (8cbcd65f-940c-49d7-a4e0-073257bc91a2, 0x, HelpDesk/Lists/servicerequests/16812_.000).
The statement has been terminated."
DOS / Batch file
stsadm -o databaserepair -url http://sharepoint.sgart.local -databasename SP_Content_Portal -deletecorruption
Per sistemarlo bisogna intervenire sul Database per recuperare lo scopeId orfano e l'id del documento.
Poi tramite la store proc_SecResetItemPerm si può resettare le permission in modo da ereditare dal parent.
Questo è le script T-SQL per eseguire la riparazione va impostato il parametro docName con il percorso ritornato nell'errore:
SQL
-- settare questa variabile con il percorso ritornato nellìerrore
DECLARE @docName nvarchar(256) = 'HelpDesk/Lists/servicerequests/16812_.000
'
-- splitto il nome per usarlo nelle query
DECLARE @i int = LEN(@docName) - CHARINDEX('/', REVERSE(@docName)) + 1;
DECLARE @dirName nvarchar(256)=substring(@docName,0,@i)
DECLARE @leafName nvarchar(256)=substring(@docName,@i+1, LEN(@docName))
SELECT @docName as docName, @dirName as dirName, @leafName as leafName
-- recupero lo scope id non associato (orfano)
DECLARE @siteid uniqueidentifier,
@webid uniqueidentifier,
@wrongScopeId uniqueidentifier,
@docid uniqueidentifier
SELECT @siteid=siteid,@webid=webid,@wrongScopeId =scopeid
FROM [Perms]
WHERE ScopeUrl = @docName
SELECT @siteid as siteId, @webid as webid, @wrongScopeId as wrongScopeId
-- cerco l'ID del documento
SELECT @docId=id
FROM AllDocs
where SiteId =@siteid AND WebId=@webid
AND DirName =@dirName and LeafName =@leafName
SELECT * FROM AllDocs WHERE ID=@docId
DECLARE @return_value int,
@NewScopeId uniqueidentifier,
@RequestGuid uniqueidentifier
-- http://msdn.microsoft.com/en-us/library/hh626037(v=office.12).aspx
EXEC @return_value = [dbo].[proc_SecResetItemPerm]
@siteid, @webid,
@wrongScopeId, @docName, @docId,
@NewScopeId = @NewScopeId OUTPUT,
@RequestGuid = @RequestGuid OUTPUT
SELECT @NewScopeId as N'NewScopeId',@RequestGuid as N'RequestGuid'
-- 0 = Successful execution.
SELECT 'Return Value' = @return_value
Verificate con attenzione i dati ritornati dalle query prima di eseguire la store procedure