saigafreak
saigafreak

Reputation: 415

Nested apoc iterate with apoc load jdbc returns "cannot conclude with CALL" message

I am calling a nested apoc procedure to iterate the loading of data via jdbc driver from mysql to ingest into neo4j. The statement looks as follows:

WITH 'jdbc:mysql://x.x.x.x:3306/schema?user=x&password=x' AS url, 'select * from table' AS query 
CALL apoc.periodic.iterate('CALL apoc.load.jdbc(url, query) YIELD row', 'MERGE (e:MYNODE {id:row.id}) SET e.id = row.id', {batchSize:1000, parallel:false})

Receiving the following result:

Neo.ClientError.Statement.SyntaxError: Query cannot conclude with CALL (must be RETURN or an update clause) (line 2, column 1 (offset: 123))
"CALL apoc.periodic.iterate('CALL apoc.load.jdbc(url, query) YIELD row', 'MERGE (e:MYNODE {id:row.id}) SET e.id = row.id', {batchSize:1000, parallel:false})"
 ^

Upvotes: 2

Views: 2826

Answers (1)

cybersam
cybersam

Reputation: 67009

  1. As the error message says, Cypher does not like you ending a query with a CALL clause (unless it is the only clause in the query). You can solve this by just adding a RETURN clause to the end of the query, even if you don't care about the result.

  2. Cypher also wants you to YIELD at least one of the returned values from a CALLed procedure, even if you don't care about it.

  3. Your 'CALL apoc.load.jdbc(url, query) YIELD row' string is not going to automatically use your url and query variables. You can solve that by using parameters.

This example solves all 3 issues:

WITH
  'jdbc:mysql://x.x.x.x:3306/schema?user=x&password=x' AS url,
  'select * from table' AS query 
CALL apoc.periodic.iterate(
  'CALL apoc.load.jdbc($url, $query) YIELD row',
  'MERGE (e:MYNODE {id:row.id}) SET e.id = row.id',
  {batchSize:1000, parallel:false, params:{url: url, query: query}}) YIELD batches
RETURN batches

Upvotes: 4

Related Questions