New to Rust? Grab our free Rust for Beginners eBook Get it free →
NodeJS MySQL Select Record

RowDataPacket is the name MySQL hands back to Node.js, and it is the line most readers get stuck on.
This is the select step end to end, from a running MySQL server to a callback whose rows you can read.
What you need to run MySQL SELECT queries in NodeJS
Three things, in dependency order. First the mysql driver on npm (install it with npm install mysql), then a MySQL server you can reach, then a table that already holds data.
This tutorial uses a products table with id, name, and price columns. If you do not have one yet, the create table guide covers setup from scratch and the insert guide fills it. The connection object itself comes from mysql.createConnection(), which we cover in detail in MySQL connections using NodeJS.
Everything below runs against a shop database with a products table like this one:
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(255),
price INT
);
INSERT INTO products VALUES
(1, 'Laptop', 700),
(2, 'Mouse', 25),
(3, 'Keyboard', 45),
(4, 'Monitor', 180);
Keep a second terminal open on the database itself while you work through the examples. Because a SELECT shows you exactly what the server holds, eyeballing the table with a plain SQL client makes every later result easier to trust. The article assumes the MySQL server is already running in the background, and if you need a local install, XAMPP starts one without touching a terminal.
| Where | Value this tutorial uses |
| host | localhost |
| database | shop |
| table | products (id, name, price) |
| rows | 4 seeded items |
Select all records from a MySQL table in NodeJS
The query() method takes your SQL string and a callback, and the second callback argument is an array with one object per matching row. That is the whole mechanism, so the smallest useful thing you can do is select every column from every row in a table and log it.
const mysql = require('mysql');
const con = mysql.createConnection({
host: "localhost",
user: "your_username",
password: "your_password",
database: "shop"
});
con.connect(function (err) {
if (err) throw err;
});
con.query("SELECT * FROM products", function (err, result) {
if (err) throw err;
console.log(result);
});
I ran this against the seeded four-row table and got the output below. This frame is the payoff of the whole page, because you see the exact shape of the return value rather than a simplified mock of it.

Save the file as app.js, run node app.js from the folder that holds it, and you should see the same four RowDataPacket lines.
How to read what query() returns
The result is an array, and each element carries the columns you selected as properties. When you select *, you get every column the table defines, so result[0].name is Laptop and result[0].price is 700. The library prints the constructor name RowDataPacket in console output because it wraps each row in that internal object for parsing, and you just read the properties off it like any other object.
Nothing here depends on the var keyword that older examples in this series use, so write const at the top level the way you would in a current codebase, and the file behaves the same.
Select specific columns from a MySQL table in NodeJS
Replacing the star with a column list changes exactly one thing: the rows come back with only those properties. So SELECT name, price FROM products returns name and price and leaves the id out.
const mysql = require('mysql');
const con = mysql.createConnection({
host: "localhost",
user: "your_username",
password: "your_password",
database: "shop"
});
con.connect(function (err) {
if (err) throw err;
});
con.query("SELECT name, price FROM products", function (err, result) {
if (err) throw err;
result.forEach(function (row) {
console.log(row.name + " costs " + row.price);
});
});
Running this gave me a friendly one-line summary per product, because forEach treats each row as a plain object you can read name and price from. I compared this loop against logging the raw result first, and the loop won because it turned the same rows into a line you can paste into a report:

| You select | The row object carries |
|---|---|
| * | every column the table defines |
| name, price | name and price only |
| name | name only |
That mapping is the whole tradeoff. Selecting named columns shrinks the payload, and because the rows still arrive as objects, your loop code reads the same whichever columns you asked for.
When a MySQL SELECT query fails in NodeJS
Both failure modes likely for a SELECT reach the same err argument, and each names itself in a property you can read. A wrong table gives ER_NO_SUCH_TABLE and a wrong column gives ER_BAD_FIELD_ERROR, so log err.code and err.sqlMessage when something does not come back.
const mysql = require('mysql');
const con = mysql.createConnection({
host: "localhost",
user: "your_username",
password: "your_password",
database: "shop"
});
con.connect(function (err) {
if (err) throw err;
});
con.query("SELECT * FROM prodcts", function (err, result) {
if (err) {
console.log("code:", err.code);
console.log("sqlMessage:", err.sqlMessage);
return;
}
console.log(result);
});
I first threw the error straight through, which killed the process and left only a stack trace to read, so I switched to logging err.code and err.sqlMessage. Running it now prints the mistake precisely, keeps the process alive, and names the object that actually has the problem:

A typo in a column name returns err.code ER_BAD_FIELD_ERROR and err.sqlMessage Unknown column in the same shape, which makes both mistakes fixable from the log alone rather than from a thrown exception at the top of the file.
Wrap up
You can now select rows from a MySQL table in Node.js, prove the result array, name the columns you want, and read the error the callback carries when the table or column is wrong.
- The one thing to remember: the callback result for a SELECT is an array of row objects, so read properties off result[0], not the string form of result.
- Next task: narrow what comes back with WHERE, covered in NodeJS MySQL Select Unique and the where guides in this series.
- Fresh project: the mysql package sits at version 2 on npm, while mysql2 has become the more actively developed native-JS driver with prepared statements and SSL support, so check both before you lock one in. Every query shape on this page works the same way through either driver’s query() method.




