'Calling RDS data service executeStatement throws "Parameter X has value with no field set"

Not sure if I clearly understood how to provide parameter values when executing rds.executeStatement command.

When I execute the below code I get this error thrown -

{
  "errorType": "BadRequestException",
  "errorMessage": "Parameter \"userId\" has value with no field set",
  "code": "BadRequestException",
  "message": "Parameter \"userId\" has value with no field set"
}

Here is my code, How am I supposed to provide the userId and givenName values to the parameters array here.

const AWS = require('aws-sdk');
var RDS = new AWS.RDSDataService({
    apiVersion: '2018-08-01'
});

exports.handler = async (event, context) => {
    var userId;
    var givenName;

    var params = {
        secretArn: 'secretArn',
        resourceArn: 'resourceArn',
        database: 'db',
        parameters: [{
                name: "userId",
                value: {
                    "stringValue": userId
                }
            },
            {
                name: "givenName",
                value: {
                    "stringValue": givenName
                }
            }
        ]
    };

    event.Records.forEach(function(record) {

        if (record.eventName == 'INSERT') {
            userId = record.dynamodb.NewImage.pk.S;
            givenName = record.dynamodb.NewImage.sk.S;
            params.sql = `INSERT INTO Users (UserId, GivenName) VALUES(:userId, :givenName);`
        }


    });
    await RDS.executeStatement(params).promise();
    console.log(params.parameters[0].value);
    return 'done';
};

UPDATE March 13th Attaching the cloudwatch logs printing out userId and givenName -

enter image description here

UPDATE March 16th - Function Updates

const AWS = require('aws-sdk');
const RDS = new AWS.RDSDataService({ apiVersion: '2018-08-01' });

exports.handler = async (event, context) => {
var userId;
var givenName;
var count = 0;

var params = {
    secretArn: 'secretArn',
    resourceArn: 'resourceArn',
    database: 'bol_db',
    parameters: [{
            name: "userId",
            value: {
                "stringValue": userId
            }
        },
        {
            name: "givenName",
            value: {
                "stringValue": givenName
            }
        }
    ]
};

const promises = event.Records.map(async function(record) {
    count++;
    context.callbackWaitsForEmptyEventLoop = false;

    if (record.eventName == 'INSERT') {
        userId = record.dynamodb.NewImage.pk.S;
        givenName = record.dynamodb.NewImage.sk.S;
        console.log('userId - ' + userId);
        console.log('givenName - ' + givenName);
        console.log('Params -'+params.parameters);
        params.sql = "INSERT INTO Users (UserId, GivenName) VALUES(:userId, :givenName);"
        let result = await RDS.executeStatement(params).promise();
        console.log('Result -' + result);
    }
});

await Promise.all(promises);
console.log(count);
return 'done';
};


Solution 1:[1]

It seems that you're setting "stringValue": userId before userId has a value. In JavaScript you can't assign userId later and expect it to be propagated to all places that you used it before.

You should try with var params = {...} inside the .map function or, alternatively, inside the .map function you can loop through the parameter list and if you find the correct one, assign the value then.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user2084865