How to INSERT INTO table(column) VALUES(value) WHERE column2 = value - sql

I am working on a Time Clock program but I am having trouble with this query:
INSERT INTO users(time_in) VALUES($2) WHERE username = $1
Table:
CREATE TABLE users (
id SERIAL PRIMARY KEY NOT NULL,
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
time_json VARCHAR,
time_in VARCHAR
);
Here is the error that I am getting:
error: syntax error at or near "time_in"
at Connection.parseE (\...\node_modules\pg\lib\connection.js:606:11)
at Connection.parseMessage (\...\node_modules\pg\lib\connection.js:403:19)
at TLSSocket.<anonymous> (\...\node_modules\pg\lib\connection.js:123:22)
at TLSSocket.emit (events.js:210:5)
at addChunk (_stream_readable.js:308:12)
at readableAddChunk (_stream_readable.js:289:11)
at TLSSocket.Readable.push (_stream_readable.js:223:10)
at TLSWrap.onStreamRead (internal/stream_base_commons.js:182:23) {
name: 'error',
length: 95,
severity: 'ERROR',
code: '42601',
detail: undefined,
hint: undefined,
position: '8',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'scan.l',
line: '1134',
routine: 'scanner_yyerror'}
Code for the function I am working on:
function postTimeIn(user, callback) {
const timeIn = getTime();
params = [user, timeIn];
const sql = 'INSERT INTO users(time_in) VALUES($2) WHERE username = $1';
pool.query(sql, params, function (err, result) { ...

The WHERE clause would make sense with an UPDATE:
UPDATE users
SET time_in = $2
WHERE username = $1;
Is that what you really want?
username should be defined UNIQUE for this - and probably in any case.
time_json should probably be type json or jsonb. time_in should probably be timestamptz.
An INSERT would not make any sense (apart from the invalid syntax), as you would have to fill in all NOT NULL columns without column default at the same time:
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,

The problem is that you are trying to insert a record with a where condition. You can only use a where condition only as a filter when you are inserting values selected from another table
like.
INSERT INTO table(column1,column2,...)
SELECT column1,column2,...
FROM another_table
WHERE condition;
In your instant you should do an update as suggested above because you are changing the attribute value of an already existing record.

Related

Prisma problem inserting into autogenerated int ID field: integer out of range for type int4

model Comment {
id Int #id #default(autoincrement())
cid String
bid String
author AppProfile #relation(fields: [bid], references: [bid])
comment String
created DateTime #default(now())
}
const results = await prisma.comment.create({
data: {
cid: req.body.cid,
comment: req.body.comment,
bid: appProfile.bid,
},
});
prisma:query INSERT INTO "public"."Comment" ("cid","bid","comment","created") VALUES ($1,$2,$3,$4) RETURNING "public"."Comment"."id"
prisma:query ROLLBACK
error - PrismaClientUnknownRequestError:
Invalid `prisma.comment.create()` invocation:
Error occurred during query execution:
ConnectorError(ConnectorError { user_facing_error: None, kind: QueryError(Error { kind: Db, cause: Some(DbError { severity: "ERROR", parsed_severity: Some(Error), code: SqlState(E22003), message: "integer out of range for type int4", detail: None, hint: None, position: None, where_: None, schema: None, table: None, column: None, datatype: None, constraint: None, file: Some("eval.go"), line: Some(65), routine: Some("init") }) }) })
at RequestHandler.handleRequestError (/Users/jmalicke/Projects/muf/dev/repos/muf/bubbles-serverless/node_modules/#prisma/client/runtime/index.js:34314:13)
at RequestHandler.request (/Users/jmalicke/Projects/muf/dev/repos/muf/bubbles-serverless/node_modules/#prisma/client/runtime/index.js:34293:12)
at async PrismaClient._request (/Users/jmalicke/Projects/muf/dev/repos/muf/bubbles-serverless/node_modules/#prisma/client/runtime/index.js:35273:16)
at async comment (webpack-internal:///(api)/./pages/api/comment/index.ts:26:25) {
clientVersion: '4.6.1',
page: '/api/comment'
}
This is strange because the id column is an Int and should be default autoincrementing. The error message complains about int4. If I look in the database the only int4 column is the id field.
It seems your users are too active, if there is more than 2.147.483.647 comment ids, the Int id has reach it max value
You can convert it to BigInt like:
id BigInt #id #default(autoincrement())
But the best is maybe to use uuid like:
id String #id #unique #default(uuid())
Int max = 2.147.483.647
BigInt max = 9.223.372.036.854.775.807
UUID max = 3.4*10^38 or 340000000000000000000000000000000000000 (thanks to Belayer)
First, make sure your provider in schema.prisma is set to "cockroachdb" if you're using CockroachDB.
For reference, CockroachDB only supports autoincrement on BigInt, while for Int's, CockroachDB uses sequence()

Transforming mongoDb json file into SQL tables

I have a mongo DB Json file that I in some way want to squeeze into a SQL database and have it make sense but I don't know what that would look like. The file looks like this:
"_id":{
"$oid":"61377659d24fd78398a5a54a"
},
"currentTotalValue":0,
"stocks":[
{
"ticker":"TSLA",
"baseCurrency":"USD",
"numberOfShares":20
},
{
"ticker":"GME",
"baseCurrency":"USD",
"numberOfShares":100
},
{
"ticker":"KINV-B",
"baseCurrency":"SEK",
"numberOfShares":50
},
{
"ticker":"BBD.B",
"baseCurrency":"CAD",
"numberOfShares":100
},
{
"ticker":"NAS",
"baseCurrency":"NOK",
"numberOfShares":20000
}
]
}
{
"_id":{
"$oid":"61377666d24fd78398a5a558"
},
"currentTotalValue":0,
"stocks":[
{
"ticker":"TSLA",
"baseCurrency":"USD",
"numberOfShares":1
},
{
"ticker":"GME",
"baseCurrency":"USD",
"numberOfShares":3457
},
{
"ticker":"KINV-B",
"baseCurrency":"SEK",
"numberOfShares":3547
},
{
"ticker":"BBD.B",
"baseCurrency":"CAD",
"numberOfShares":5768
},
{
"ticker":"NAS",
"baseCurrency":"NOK",
"numberOfShares":100000
}
]
}
So in SQL is this two separate tables with one portfolio in each or?
And if so what would those tables look like?
It depends on how one interprets the file. One could say, there are two portfolios which are described by some oid and a currentTotalValue two which the stocks belong to.
CREATE TABLE portfolios (
oid VARCHAR(24) NOT NULL PRIMARY KEY,
currentTotalValue INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE stocks (
id INTEGER NOT NULL PRIMARY KEY,
portfolio_id VARCHAR(24) NOT NULL,
ticker VARCHAR(20) NOT NULL,
baseCurrency VARCHAR(3) NOT NULL,
numberOfShares INTEGER NOT NULL,
CONSTRAINT fk_stocks_portfolios
FOREIGN KEY(portfolio_id) REFERENCES portfolios(oid)
);
If you don't need the portfolio you can drop it and remove the foreign key constraint from table stocks:
CREATE TABLE stocks (
id INTEGER NOT NULL PRIMARY KEY,
portfolio_id VARCHAR(24) NOT NULL,
ticker VARCHAR(20) NOT NULL,
baseCurrency VARCHAR(3) NOT NULL,
numberOfShares INTEGER NOT NULL
);
Warning: this is just a rough sketch to get a basic idea. Depending on the used DBMS you could use an auto increment value for the stocks id.

Sequlize Query get last added value

I am using Sequlize. I have a table status_config in this table I have a column create_time as timestamp( 2021-06-02 12:04:52.293977). Now I need to query on this table and get the latest value created on this table.
status_config.findOne({ where: created_time **need to implement here to get last added value})
We can use order by [['createdAt', 'desc']]
let last_status_config = await status_config.findOne({
order:[['createdAt', 'desc']]
});
console.log(JSON.parse(JSON.stringify(last_status_config)))
Output
{ id: 19, name: 'test_last', password: null, confirmation: null }

Sequelize Postgres - How to use ON CONFLICT for unique?

I am implementing sequelize into my NodeJS application. Before this, I was using a written INSERT query that used ON CONFLICT (field) DO NOTHING to handle not inserting records where a value needed to be unique.
const sql = 'INSERT INTO communications (firstname, lastname, age, department, campus, state, message_uuid) VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (message_uuid) DO NOTHING';
const values = [val.firstName, val.lastName, val.age, val.department, val.campus, val.state, message_uuid];
Is there support for this in sequelize where I can define the same thing within a model? Or perhaps a better way to handle it?
Essentially, if a record already exists in the table in the column with message_uuid = 123 and another record try's to insert that has that same value, it ignores it and does nothing.
You can use public static bulkCreate(records: Array, options: Object): Promise<Array> method with options.ignoreDuplicates.
Ignore duplicate values for primary keys? (not supported by MSSQL or Postgres < 9.5)
Besides, it's important to add a unique constraint for the message_uuid field on the model. So that the query will use ON CONFLICT DO NOTHING clause of Postgres.
For example, "sequelize": "^5.21.3" and postgres:9.6:
import { sequelize } from '../../db';
import { Model, DataTypes } from 'sequelize';
class Communication extends Model {}
Communication.init(
{
firstname: DataTypes.STRING,
lastname: DataTypes.STRING,
age: DataTypes.INTEGER,
message_uuid: {
type: DataTypes.INTEGER,
unique: true,
},
},
{ sequelize, tableName: 'communications' },
);
(async function test() {
try {
await sequelize.sync({ force: true });
// seed
await Communication.create({ firstname: 'teresa', lastname: 'teng', age: 32, message_uuid: 123 });
// test
await Communication.bulkCreate([{ firstname: 'teresa', lastname: 'teng', age: 32, message_uuid: 123 }], {
ignoreDuplicates: true,
});
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
Execution result:
Executing (default): DROP TABLE IF EXISTS "communications" CASCADE;
Executing (default): DROP TABLE IF EXISTS "communications" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "communications" ("id" SERIAL , "firstname" VARCHAR(255), "lastname" VARCHAR(255), "age" INTEGER, "message_uuid" INTEGER UNIQUE, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'communications' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "communications" ("id","firstname","lastname","age","message_uuid") VALUES (DEFAULT,$1,$2,$3,$4) RETURNING *;
Executing (default): INSERT INTO "communications" ("id","firstname","lastname","age","message_uuid") VALUES (DEFAULT,'teresa','teng',32,123) ON CONFLICT DO NOTHING RETURNING *;
Check the database, there is only one row as expected.
node-sequelize-examples=# select * from communications;
id | firstname | lastname | age | message_uuid
----+-----------+----------+-----+--------------
1 | teresa | teng | 32 | 123
(1 row)
see the new UPSERT feature in Sequelize v6:
https://sequelize.org/api/v6/class/src/model.js~model#static-method-upsert
Implementation details:
MySQL - Implemented with ON DUPLICATE KEY UPDATE`
PostgreSQL - Implemented with ON CONFLICT DO UPDATE.
If update data contains PK field, then PK is selected as the default conflict
key. Otherwise first unique constraint/index will be selected, which
can satisfy conflict key requirements.
SQLite - Implemented with ON CONFLICT DO UPDATE
MSSQL - Implemented as a single query using MERGE and WHEN (NOT) MATCHED THEN
as second argument of Model.create you can provide onConflict prop, please read the documentation

SQL query to search a String without key, in a Column which has only JSON data

I need to search a string, for example 'RecId' in a column which has only JSON data.
First Cell JSON Data:
{
"AuditedFieldsAndRelationships": null,
"AuditObjectChanges": false,
"CalculatedRules": {
"AuditHistoryDescription": {
"Calculated": "Always",
"CalculatedExpression": {
"Description": null,
"FieldRefs": ["RecId", "Rel_CIComponent_InstalledApplication_Name", "Rel_Software_Id", "Rel_Software_Name"]
}
}
}
}
Image:
Database: Microsoft SQL Server 2014
I got pretty similar problem solution in link but it is with respect to key
SELECT * FROM #table CROSS APPLY OPENJSON(Col,'$.Key') WHERE value ='SearchedString'
but it is showing error Invalid object name 'OPENJSON'
For that error, I tried the below solution given in link
SELECT compatibility_level FROM sys.databases WHERE name = 'DataBaseName';
But getting the below error:
Could someone help me out here.