Dúvida While dentro de um While

Tenho uma API no Protheus que faz uma consulta na SC7 utilizando o TcQuery na SC7 informação de cabeçalho e itens ficam na mesma tabela e eu quero montar um json com a seguinte estrutura:

{
      "cabecalho": { .... },
      "itens": [{...},{...}]
}

Para isso eu montei o seguinte código em ADVPL:

dbSelectArea("SC7")

	cQrySC7 := " SELECT * "
	cQrySC7 += " FROM " + RetSqlName("SC7") + " "
	cQrySC7 += " WHERE D_E_L_E_T_ = ' ' "

	TcQuery cQrySC7 New Alias cQryAli

	If cQryAli->(!Eof())

		oObjGet["success"]	:= .T.
		oObjGet["message"]	:= ""
		oObjGet["data"]		:= {}

		While cQryAli->(!Eof())

			oObjDta := JsonObject():New()
			oObjDta["itens"] := {}

			// Busca os itens do pedido de compra
			oObjItens := JsonObject():New()

			cQryItem := " SELECT * "
			cQryItem += " FROM " + RetSqlName("SC7") + " "
			cQryItem += " WHERE C7_NUM = '" + cQryAli->C7_NUM + "' "
			cQryItem += " AND D_E_L_E_T_ = ' ' "
			TcQuery cQryItem New Alias cAliItem

			If cAliItem->(!Eof())
				cAliItem->( DbGotop() )
				While cAliItem->(!Eof())
					oObjItens["codigo_produto"] := validaRetornoBanco(cAliItem->C7_PRODUTO)
					oObjItens["descricao_produto"] := validaRetornoBanco(cAliItem->C7_DESCRI)
					oObjItens["quantidade"] := validaRetornoBanco(cAliItem->C7_QUANT)
					oObjItens["preco_unitario"] := validaRetornoBanco(cAliItem->C7_PRECO)
					oObjItens["preco_total"] := validaRetornoBanco(cAliItem->C7_TOTAL)
					oObjItens["desconto_item"] := validaRetornoBanco(cAliItem->C7_VLDESC)
					oObjItens["condicao_pagamento"] := validaRetornoBanco(cAliItem->C7_COND)
					oObjItens["codigo_fornecedor"] := validaRetornoBanco(cAliItem->C7_FORNECE)
					oObjItens["data_entrega"] := validaRetornoBanco(cAliItem->C7_DATPRF)
					oObjItens["observacoes"] := validaRetornoBanco(cAliItem->C7_OBSM)
					oObjItens["aliquota_ipi"] := validaRetornoBanco(cAliItem->C7_IPI)
					oObjItens["nmr_solicitacao_compra"] := validaRetornoBanco(cAliItem->C7_NUMSC)
					oObjItens["valor_frete"] := validaRetornoBanco(cAliItem->C7_VALFRE)

					aAdd( oObjDta["itens"], oObjItens )
					cAliItem->(dbSkip())
				EndDo
			Else
				lRet := .F.
				ConOut("Itens do pedido de compra não encontrado!")
				SetRestFault(404, EncodeUTF8("Itens do pedido de compra não encontrado"))
			EndIf

			// Transformando os dados do SQL para o objeto JSON
			oObjDta["data_emissao_pedido"] := validaRetornoBanco(cQryAli->C7_EMISSAO)
			oObjDta["codigo_fornecedor"] := validaRetornoBanco(cQryAli->C7_FORNECE)
			oObjDta["loja_fornecedor"] := validaRetornoBanco(cQryAli->C7_LOJA)
			oObjDta["condicao_pagamento"] := validaRetornoBanco(cQryAli->C7_COND)
			oObjDta["contato_fornecedor"] := validaRetornoBanco(cQryAli->C7_CONTATO)
			oObjDta["filial_entrada_mercador"] := validaRetornoBanco(cQryAli->C7_FILENT)
			oObjDta["moeda_pedido"] := validaRetornoBanco(cQryAli->C7_MOEDA)
			oObjDta["taxa_cambio"] := validaRetornoBanco(cQryAli->C7_TXMOEDA)
			oObjDta["numero_solicitacao"] := validaRetornoBanco(cQryAli->C7_NUMSC)

			aAdd( oObjGet["data"], oObjDta )

			cQryAli->(dbSkip())

		EndDo
	Else

		lRet := .F.
		ConOut("Pedido não localizados!")
		SetRestFault(404, EncodeUTF8("Pedido não localizados"))

	EndIf

	// cAliItem->(dbCloseArea())
	cQryAli->(dbCloseArea())

Mas dessa maneira a API me retorna um status 500 com o erro “internal server error”, e se eu remover o While que executa dentro desse While ele retorna corretamente.
Minha dúvida, é possível utilizar um While dentro de outro While, se não como posso fazer essa busca?

1 curtida

@BernardoGualberto boa tarde.

No console, qual erro que ele mostra?

Tem outra maneira de fazer isso, pode usar uma query só.

Usando um While dentro do outro testando o numero do pedido, ordene a query principal por filial+numero

Então isso que estranhei, pois no console não retorna nada.
Mas nem cheguei a pensar em fazer em uma query só, vou fazer isso

No console do rest deve estar sim dando algum erro.

Estou executando o appserver.exe pelo modo console, e está retornando o seguinte:

[INFO ][SERVER] Web Monitor - restarted (1.193000 seconds)

*** Loading dbapi.dll
*** dbapi.dll Build 20230303-20240215 RELEASE (API Version: 23.1.1.3)

HTTPV11 is ready.
Listening port 8990
URL Paths /rest/

[INFO ][SERVER] [Thread 11364] HTTP server HTTPREST, port: 8990, started on ID: 6

[INFO ][SERVER] [Thread 11364] HTTP Server - HTTPREST, started on port: 8990.

*** Loading dbapi.dll
*** dbapi.dll Build 20230303-20240215 RELEASE (API Version: 23.1.1.3)
[ VTWSFORN ] [ 26/06/2025 - 15:55:04 ] GET pedidos de compra → Inicio
/-------------------------------------------------------
-------------------------------------------------------
/


Estou alterando a query para ter somente uma execução.