How to execute dynamic DDL statements? #26295
import { SQL } from "bun";
// Assuming the REST API returns data.
const datas = [
{
syncState: "BaseIndirect",
messageType: "PositionReportClassAScheduled",
repeatIndicator: "0",
transponderClass: "B",
valid: "true",
second: "39",
navigationStatus: "UnderwayUsingEngine",
mmsi: "413825213",
courseOverGround: "107.5",
speedOverGround: "6.400000095367432",
rateOfTurn: "0",
trueHeading: "511",
longitude: "139.839637",
latitude: "35.721631",
shipName: "",
shipType: "Cargo",
draught: "0",
callsign: "",
eta: "0",
imo: "0",
destination: "0",
shipWidth: "13",
shipLength: "119",
collectTime: "2026-01-17 14:59:40",
},
{
syncState: "UTCDirect",
messageType: "ExtendedClassBEquipmentPositionReport",
repeatIndicator: "0",
transponderClass: "A",
valid: "true",
second: "60",
navigationStatus: "UnderwayUsingEngine",
mmsi: "413773734",
courseOverGround: "229.89999389648438",
speedOverGround: "0.0",
rateOfTurn: "-128",
trueHeading: "511",
longitude: "139.847856",
latitude: "35.675789",
shipName: "RUILIN",
shipType: "Cargo",
draught: "0",
callsign: "0",
eta: "0",
imo: "0",
destination: "0",
shipWidth: "15",
shipLength: "92",
collectTime: "2026-01-17 14:59:41",
},
];
const mysql = new SQL("mysql://xxx:xxx@mysql.sqlpub.com:3306/test");
const ddl = Object.keys(datas[0])
.reduce(
(sql, key) => sql.concat(` \`${key}\` VARCHAR(255), \n`),
"CREATE TABLE IF NOT EXISTS `ais_data` ( \n"
)
.slice(0, -3)
.concat("\n) ");
// Here's an error.
await mysql`${ddl}`;
// // It's OK here.
// await mysql`CREATE TABLE IF NOT EXISTS \`ais_data\` ( \`syncState\` VARCHAR(255), \`messageType\` VARCHAR(255), \`repeatIndicator\` VARCHAR(255), \`transponderClass\` VARCHAR(255), \`valid\` VARCHAR(255), \`second\` VARCHAR(255), \`navigationStatus\` VARCHAR(255), \`mmsi\` VARCHAR(255), \`courseOverGround\` VARCHAR(255), \`speedOverGround\` VARCHAR(255), \`rateOfTurn\` VARCHAR(255), \`trueHeading\` VARCHAR(255), \`longitude\` VARCHAR(255), \`latitude\` VARCHAR(255), \`shipName\` VARCHAR(255), \`shipType\` VARCHAR(255), \`draught\` VARCHAR(255), \`callsign\` VARCHAR(255), \`eta\` VARCHAR(255), \`imo\` VARCHAR(255), \`destination\` VARCHAR(255), \`shipWidth\` VARCHAR(255), \`shipLength\` VARCHAR(255) )`;
await mysql`INSERT INTO \`ais_data\` ${mysql(datas)}`;I want to dynamically create a table in MySQL and store data based on the data returned from the REST API. The following error occurred: |
Replies: 1 comment 1 reply
|
@chenmonster the fix: use const mysql = new SQL("mysql://xxx:xxx@mysql.sqlpub.com:3306/test");
// DDL -- use .unsafe() since table/column names can't be parameterized
const ddl = Object.keys(datas[0])
.reduce((sql, key) => sql.concat(` \`${key}\` VARCHAR(255),\n`), "CREATE TABLE IF NOT EXISTS `ais_data` (\n")
.slice(0, -2)
.concat("\n)");
await mysql.unsafe(ddl);
// DML -- tagged template is fine here, values get properly parameterized
await mysql`INSERT INTO \`ais_data\` ${mysql(datas)}`;the distinction is in one warning: |
@chenmonster the
?in the error is the giveaway. when you writeawait mysql\${ddl}``, bun's tagged template sends the entire DDL string as a bind parameter via mysql's prepared statement protocol. mysql can't parameterize DDL statements (table names, column definitions, etc.), only DML values.fix: use
sql.unsafe()for DDL, keep parameterized queries for DML: