Pergunta

Tenho menos de 5.000 itens em minha biblioteca.Quero obter 530 itens por IDs.Então, estou usando a seguinte consulta.

<Where>
  <In>
    <FieldRef Name="ID" />
    <Values>
       <Value Type="Number">1</Value>
       <Value Type="Number">2</Value>
       .
       .
       .
       <Value Type="Number">530</Value>
    </Values>
  </In>
</Where>

Se eu usar esta consulta na lista, durante a iteração de SPListItemCollection, ocorrerá a seguinte exceção.

System.ArgumentException: Value does not fall within the expected range.
   at Microsoft.SharePoint.Library.SPRequestInternalClass.GetListItemDataWithCallback2(IListItemSqlClient pSqlClient, String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pPagingPrevCallback, ISPDataCallback pFilterLinkCallback, ISPDataCallback pSchemaCallback, ISPDataCallback pRowCountCallback, Boolean& pbMaximalView) 
   at Microsoft.SharePoint.Library.SPRequest.GetListItemDataWithCallback2(IListItemSqlClient pSqlClient, String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pPagingPrevCallback, ISPDataCallback pFilterLinkCallback, ISPDataCallback pSchemaCallback, ISPDataCallback pRowCountCallback, Boolean& pbMaximalView) 
   at Microsoft.SharePoint.SPListItemCollection.EnsureListItemsData() 
   at Microsoft.SharePoint.SPListItemCollection.GetEnumerator() 

Se eu executar novamente a consulta com valores do operador IN menores que 500, SPListItemCollection não lançará uma exceção.

A operadora CAML IN tem limite de 500 itens menores que iguais?Ou existe alguma outra abordagem melhor.

Foi útil?

Solução

Com certeza parece que sim pela sua história, mas não há uma solução alternativa muito fácil para isso?

<Where>
  <Or>
      <In>
        <FieldRef Name="ID" />
        <Values>
           <Value Type="Number">1</Value>
           <Value Type="Number">2</Value>
           .
           .
           .
           <Value Type="Number">499</Value>
        </Values>
      </In>
      <In>
        <FieldRef Name="ID" />
        <Values>
           <Value Type="Number">500</Value>
           <Value Type="Number">501</Value>
           .
           .
           .
           <Value Type="Number">999</Value>
        </Values>
      </In>
   </Or>
</Where>

e assim por diante, com mais aninhamentos se for superior a 1000 e assim por diante.

Outras dicas

Não posso comentar devido à baixa reputação, então poste como resposta, os puristas perdoam.

Dividir um elemento In de 500 em várias tags Or aninhadas não funciona, para meu desespero.O limite é de 500 elementos, aparentemente.

Tentei quebrar usando um limite de 500 elementos, 400, 300, 200, 100, e a consulta SPServices falhou, retornando:500 Erro interno do servidor com o seguinte responseText:

Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown.

Tentar atualizar no máximo 500 elementos (com uma única tag In ou quebrar usando Or aninhado por 400, 300, 200, 100 elementos) funciona.Então a consulta retorna 200 sucessos.Que eu saiba, também deve haver algum limite de tags Or aninhadas.

Estou a usar:SPServices 2014.01, jQuery 1.11, SharePoint 2013:

$().SPServices.SPUpdateMultipleListItems({
    listName: "some list display name",
    CAMLQuery: CAMLQuery,
    valuepairs: [["static name of the field", 1]],
    completefunc: function (xData) {
        if (xData.status !== 200) {
            console.log("failure");
        }
    }
});

Exemplo de consulta 5 * 100 + 1 que falha porque existem 501 elementos:

<Query>
  <Where>
    <Or>
      <In>
        <FieldRef Name='ID' LookupId='TRUE' />
        <Values>
          100 times <Value Type='Lookup'>2688</Value>
        </Values>
      </In>
      <Or>
        <In>
          <FieldRef Name='ID' LookupId='TRUE' />
          <Values>
            100 times value
          </Values>
        </In>
        <Or>
          <In>
            <FieldRef Name='ID' LookupId='TRUE' />
            <Values>
              100 times value
            </Values>
          </In>
          <Or>
            <In>
              <FieldRef Name='ID' LookupId='TRUE' />
              <Values>
                100 times value
              </Values>
            </In>
            <Or>
              <In>
                <FieldRef Name='ID' LookupId='TRUE' />
                <Values>
                  100 times value
                </Values>
              </In>
              <In>
                <FieldRef Name='ID' LookupId='TRUE' />
                <Values>
                  <Value Type='Lookup'>3089</Value>
                </Values>
              </In>
            </Or>
          </Or>
        </Or>
      </Or>
    </Or>
  </Where>
</Query>

Também não posso comentar, mas o que fiz quando me deparei com esse tipo de situação (sim, encontrei essa limitação), foi executar a consulta usando o mínimo e máximo do ID

<Where>
    <And>
        <Geq><FieldRef Name='ID' /><Value Type='Counter'>x</Value></Geq>
        <Leq><FieldRef Name='ID' /><Value Type='Counter'>y</Value></Leq>
    </And>
</Where>

Então, supondo que eu tenha os IDs que realmente desejo em algum tipo de enumerável, use o LINQ para obter os itens que você realmente deseja dos resultados da consulta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top