И ошибок при этом не возвращается?
Сама MySQL не оперирует не именованными параметрами (?), этим занимается расширение. Я не знаю Node, как в нем это все работает и есть ли вообще такое, но обычно эти параметры нужно связать с данными запроса. Для не именованных параметров обязательное условие, это равенство количества не именованных параметров и данных запроса, а порядок следования данных должен соответствовать порядку их описания не именованными параметрами в запросе. При связывании описывается и тип данных, для каждого значения. Подставляемые в запрос не именованные параметры обрабатываются во время подготовления запроса, в котором затем будут сопоставлены переданные значения.
Во время выполнения подготовленного запроса значения определенные как string будут экранированы, а значения определенные как integer, double и blob будут приведены к этим типам. Это исключает sql-инъекцию во время запроса.
Но исключение инъекции не решает проблемы соответствия данных типам полей, то есть не будет возникать ошибок если данные не соответствуют, запрос успешно выполнится, а в базе будет "мусор". Для предотвращения этого данные пришедшие извне нужно подвергать фильтрации если недопустимы несоответствия, иначе в дальнейшем эти данные могут порождать ошибки или иные проблемы.
По крайней мере в данном запросе есть попытка обезопасить запрос в отличие от запроса
в этой теме. Там что пришло, то отправили в запрос, по крайней мере не наблюдается ни экранирования, ни приведения типов, вообще ничего. Учтите, что если "прокатило", характер запроса не позволил выполнить имеющуюся в данных инъекцию, то это не означает, что она не сработает впоследствии. Запросы к базе могут использовать данные в ней как параметры запроса, и молчащие до поры до времени "грабли" в ней обязательно когда-то выстрелят.