SQLite, Error NOT NULL constraint failed on Primary Key column - react-native

I have problem while using expo-sqlite. Whenever I tried to insert values to table (exclude the id), it always throw the NOT NULL constraint error. If I'm not mistaken, Primary Key will automatically auto_increment means that I don't really need to provide id for inserting a new row, is this right?
Edit: tried to test the SQL commands in SQLite Playground and it works. I think it might have something to do with my syntax or something wrong with the package I'm using (expo-sqlite)
Here are my codes:
useEffect(() => {
// Create new tables if no database exist
db.transaction((tx) => {
tx.executeSql(
'create table if not exists categories (id integer, name varchar(255), primary key (id));',
[],
() => {},
(tx, err) => {
console.log('this is the error beginning', err);
return true;
}
);
tx.executeSql(
'create table if not exists transactions (id integer, tx_datetime datetime, tx_value varchar(255), note varchar(255), tx_day integer, tx_month integer, tx_year varchar(255), category integer, tx_type integer default 0, primary key (id), foreign key (category) references test_categories (id));',
[],
() => {},
(tx, err) => {
console.log('this is the error beginning two', err);
return true;
}
);
});
}, []);
db.transaction((tx) => {
// tx.executeSql(
// 'insert into transactions (tx_datetime, tx_value, note, tx_day, tx_month, tx_year, tx_type, category) values (?,?,?,?,?,?,?,?);',
// [
// data.tx_datetime,
// data.tx_value,
// data.note,
// data.tx_day,
// data.tx_month,
// data.tx_year,
// data.tx_type,
// data.category,
// ],
// () => {},
// (tx, err) => {
// console.log('add error', err);
// return true;
// }
// );
tx.executeSql(
'insert into categories(name) values("testing");',
[],
() => {},
(tx, err) => {
console.log('errro again', err);
return true;
}
);
});

Honestly, not really sure what fixes it. But here are the new code that I'm using. Probably deleting and creating a new table with the correct query does the job like what #forpas said in the comment.
db.transaction((tx) => {
tx.executeSql(
'create table if not exists categories (id integer primary key not null , name varchar(255));',
[],
() => {
console.log('this is created');
},
(tx, err) => {
console.log('this is the error beginning', err);
return true;
}
);
tx.executeSql(
'create table if not exists transactions (id integer primary key, tx_datetime datetime, tx_value varchar(255), note varchar(255), tx_day integer, tx_month integer, tx_year varchar(255), category integer, tx_type integer default 0, foreign key (category) references test_categories (id));',
[],
() => {
console.log('table two created');
},
(tx, err) => {
console.log('this is the error beginning two', err);
return true;
}
);
});
and here's the second one
tx.executeSql(
'insert into categories (name) values (?)',
['testing'],
() => {},
(tx, err) => {
console.log('errro again', err);
return true;
}
);

Related

SQL Query for insert multiple items in nodejs

Shoes.create = (newshoes, result) => {
sql.query("INSERT INTO shoes SET ? ", newshoes, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
console.log("created shoes: ", { id: res.insertId, ...newshoes });
result(null, { id: res.insertId, ...newshoes });
});
};
in that INSERT INTO shoes SET ? there is supposed to be two parameters (name and description). Doing this "INSERT INTO shoes SET ? ? ", newshoes, desc along with this line
console.log("created shoes: ", { id: res.insertId, ...newshoes });
result(null, { id: res.insertId, ...newshoes });
created an error.
I'm learning nodejs and sql query. What is the solution to the error?
In SQL you have to specify column names for insert and values in a different way.
So correct query would be:
INSERT INTO shoes(column1, column2) VALUES (value1, value2);
Look for examples in your database documentation, for PostgreSQL it would be:
https://www.postgresql.org/docs/current/sql-insert.html

I have an sql error when i type in a command

So I'm trying to make dynamic command handling for my bot, but it just doesn't work. Everything works without dynamic command handling.
So this is there error i get when i type in command !work:
UniqueConstraintError [SequelizeUniqueConstraintError]: Validation error
at Query.formatError (C:\Users\mmede\Desktop\Discord Bot\node_modules\sequelize\lib\dialects\sqlite\query.js:409:16)
at Query._handleQueryResponse (C:\Users\mmede\Desktop\Discord Bot\node_modules\sequelize\lib\dialects\sqlite\query.js:72:18)
at Statement.afterExecute (C:\Users\mmede\Desktop\Discord Bot\node_modules\sequelize\lib\dialects\sqlite\query.js:246:27)
at Statement.callbackTrampoline (internal/async_hooks.js:129:14) {
errors: [
ValidationErrorItem {
message: 'user_id must be unique',
type: 'unique violation',
path: 'user_id',
value: '485384232131100693',
origin: 'DB',
instance: [users],
validatorKey: 'not_unique',
validatorName: null,
validatorArgs: []
}
],
fields: [ 'user_id' ],
parent: [Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: users.user_id] {
errno: 19,
code: 'SQLITE_CONSTRAINT',
sql: 'INSERT INTO `users` (`user_id`,`balance`) VALUES ($1,$2);'
},
original: [Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: users.user_id] {
errno: 19,
code: 'SQLITE_CONSTRAINT',
sql: 'INSERT INTO `users` (`user_id`,`balance`) VALUES ($1,$2);'
},
sql: 'INSERT INTO `users` (`user_id`,`balance`) VALUES ($1,$2);'
}
and this is my work script:
const Discord = require('discord.js');
const { Users, CurrencyShop } = require('../dbObjects');
const currency = new Discord.Collection();
Reflect.defineProperty(currency, 'add', {
//eslint-disable-next-line func-name-matching
value: async function add(id, amount) {
const user = currency.get(id);
if (user) {
user.balance += Number(amount);
return user.save();
} else {
try {
const newUser = await Users.create({ user_id: id, balance: amount });
currency.set(id, newUser);
return newUser;
} catch (err) {
// print the error details
console.log(err);
}
}
},
});
module.exports = {
name: 'work',
description: 'balancas',
execute(message, async) {
message.channel.send('You hacked someones computer and you gained 1million vbucks')
currency.add(message.author.id, 1000000);
}
}
If anyone would like to help me I would really appreciate it. I'm new to sql so that would be great if you explained where I made the mistake.
The problem is that you're trying to insert an entry (user) into the users table with a user_id that already exists.
Since the users table has a UNIQUE constraint, that column is a primary key for the table and there can be no duplicate user_ids i.e. no two users can have the same user_id.
If you want to edit a particular user, try the update command.

Node js SQL Transactions REST

I have implemented a REST API with express.js. I use it to connect to my database. The database has to tables. One is the table Person and the other is called Pet.
app.post('/persons', (req, res, next) => {
let firstname = req.body.firstname;
let lastname = req.body.lastname;
let petname = req.body.petname;
if (!firstname) {
return res.status(400).send({ error: true, message: 'Please provide first name' });
}else if (!lastname) {
return res.status(400).send({ error: true, message: 'Please provide last name' });
}else if (!petname) {
return res.status(400).send({ error: true, message: 'Please provide pet name' });
}
When i call this post method i want to check if a certain petname already exists in the database. If so, then get the petID and insert it with the first name and the last name in the table Person, so that a person is linked with a pet. If this petname does not exist, then create a new pet with this name and a new id in the table Pet. Then again save the id and the first name and last name to the table Person. So every petname should only exist once.
I know how to write the Person into the database:
Conn.query("INSERT INTO Person SET ? ", { FirstName: firstname, LastName: lastname, PetID: petid }, function (error, results, fields) {
if (error) throw error;
return res.send({ error: false, data: results, message: 'New person has been created successfully.' });
});
But now i still need the petID, if available, and if not create a new pet in the DB and return the id.
How do i do that?
I think checking before creating transaction is your option.
If pet exists you will get it's id, and if not - create new pet and also get the id.
I wrote a small sql script for psql:
WITH pet AS (
WITH new_row AS (
INSERT INTO Pets (id)
SELECT '{id}' WHERE NOT EXISTS (SELECT * FROM Pets WHERE id = '{id}')
RETURNING *
)
SELECT * FROM new_row
UNION
SELECT * FROM Pets WHERE id = '{id}' LIMIT 1
RETURNING *
)
INSERT INTO Person SET pet_id=pet.id;
SOURCE FROM RELATED QUESTION
Next step is creating transaction for person. Now you already have your pet id.
So i tried this but it does not work.
Conn.beginTransaction(function(error){
if (error) throw error;
Conn.query('Select PetID FROM Pet WHERE Petname = ' + mysql.escape(petname), function (error, results, fields){
if (error) {
connection.rollback(function() {
throw error;
});
}
else {
if (!results) {
Conn.query('INSERT INTO Pet SET ? ', { Petname: petname }, function (error, results, fields){
if (error) {
connection.rollback(function() {
throw err;
});
}
return res.send({ error: false, data: results, message: 'New pet has been created successfully.' });
});
}
let petid = results.insertId;
Conn.query('INSERT INTO Person SET ? ', { FirstName: firstname, LastName: lastname, PetID: petid}, function (error, results, fields){
if (error) {
connection.rollback(function() {
throw error;
});
}
Conn.commit;
return res.send({ error: false, data: results, message: 'New person has been created successfully.' });
});
}
});
});
What is wrong with this transaction?

AWS RDS BatchExecuteStatementRequest

I am trying to update my RDS Aurora database with simple information.
import * as AWS from 'aws-sdk';
import { BatchExecuteStatementRequest } from 'aws-sdk/clients/rdsdataservice';
const RDS = new AWS.RDSDataService();
export const create = async (event: any) => {
try {
const params: BatchExecuteStatementRequest = {
secretArn: 'arn:aws:secretsmanager:XXXXXXXXXXXXXXXXXXX',
resourceArn: 'arn:aws:rds:XXXXXXXXXXXXXXXXXXXXX',
schema: 'PUBLIC',
database: 'test_db',
parameterSets: [
[
{
name: 'FirstName',
value: {
stringValue: 'Joe',
}
},
{
name: 'LastName',
value: {
stringValue: 'Doe'
}
}
],
[
{
name: 'FirstName',
value: {
stringValue: 'Joyer',
}
},
{
name: 'LastName',
value: {
stringValue: 'Doyer'
}
}
]
],
sql: 'INSERT INTO test_table (FirstName, LastName) VALUES (:FirstName, :LastName)'
};
const res = await RDS.batchExecuteStatement(params).promise();
console.log({ result: res, params });
return {
statusCode: 200,
body: JSON.stringify(res)
};
} catch (err) {
console.error(err);
return {
statusCode: err.statusCode || 500,
headers: { 'Content-Type': 'text/plain' },
body: 'Could not create the note.'
};
}
};
This will generate an error:
{ BadRequestException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ’(’Joyer’, ‘Doyer’)' at line 1 }
The weird part is, it's working if I only add ONE person in parameterSets, so the error occur when I try to have more than one array.
I created my db in AWS console, this is the query for that:
CREATE DATABASE IF NOT EXISTS test_db;
USE test_db;
CREATE TABLE IF NOT EXISTS test_table (
Id int NOT NULL AUTO_INCREMENT,
FirstName varchar(255),
LastName varchar(255),
PRIMARY KEY (Id)
);
I found the problem while I was writing the question, thought I will share it here anyway.
You can NOT have AUTO_INCREMENT!
This was the error, just remove it and everything works.
This was a couple of fun hours.....

make a db name a variable in webSQL

I'm looking for a solution to make the database name of my webSQL query a variable , if it's possible, I have not found any clue yet.
I'm working on transformation of .json to webSql.
Here's some parts of my code :
$(document).ready(function() {
CreateTable();
$.getJSON('dataMultiTable.json',function(data){
console.log(data);
$.each(data.People, function(index, People){
InsertData(baseUtilisateur,People.nom,People.prenom,People.tel,People.email,People.adresse);
});
});
return false;
});
function CreateTable() {
db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS baseUtilisateur (id INTEGER PRIMARY KEY AUTOINCREMENT, prenom TEXT, nom TEXT,tel TEXT,email TEXT,adresse TEXT)");
});
}
function InsertData(entryNom,entryPrenom,entryTel,entryMail,entryAdresse) {
var insertStatement = "INSERT INTO baseUtilisateur (prenom,nom,tel,email,adresse) VALUES (?,?,?,?,?)";
db.transaction(function(tx) {
tx.executeSql(insertStatement,[entryPrenom,entryNom,entryTel,entryMail,entryAdresse]);
});
}
So can I make the 'baseUtilisateur' a variable ?
I already have tried to use the ? , [] which is used in the insert into query for the values but it doesnt work.
Thanks,