You've got quite a lot going on here in this example. I think I can give you a couple of suggestions though that can make this drastically easier -- the code you've got is working hard, but there are some better methods I think which would simplify this.
There's so much code here, I need to suggest you approach this a different way. The tactic of looking through the success & failure cases and spotting the tiny syntax difference isn't a good use of time.
Define a SQL view if possible.
Your actual SQL query is doing a lot of text parsing and replacement. I bet this is a big source of your syntax errors, because you're trying to put nested strings inside of strings inside of Cypher, and this is very hard to read and get right. So first, on your SQL database, ideally do this:
CREATE VIEW myGraphView AS (big select statement here)
Then inside of your Cypher code, your SQL query is easy: "SELECT * FROM myGraphView"
Redo your Maps
You have a lot of code that looks like this:
(CASE WHEN row.attrname = 'enodebattributes_enodebname' then n END).enodebattributes_enodebname = row.attrvalue,
There are like 2 dozen of these? It looks like what you're doing is mapping a key/value structure (row.attrname/row.attrvalue) into a set of cypher properties. There's a much easier way to do this with way less syntax. It would work like this:
WITH {
enodebattributes_enodebname: 'enodebattributes_enodebname'
(...)
} AS mappings
MERGE (n:EQUIPMENT { EQUIP_INST_ID: row.EQUIP_INST_ID })
ON MATCH SET
n[coalesce(mappings[row.attrname], "defaultProp")] = row.attrvalue
Basically this would have you focus on writing the mappings between your "key" fields coming from SQL and your "property names" in your graph nodes. Then the way you set those values is always the same using the simple mapping. The coalesce is there to set a default property if no mapping is found.
If you make these two changes, your code will get way cleaner, way shorter, and any syntax errors you have will be easy to spot