Mybatis Insert PK manually - mybatis

I am trying to single insert data into table with assigned PK. Manually assiging PK.
XML file
<insert id = "insertStd" parameterType = "com.org.springboot.dao.StudentEntity" useGeneratedKeys = "false" keyProperty = "insertStd.id", keyColumn = "id">
INSERT INTO STUDENT (ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL )
VALUES (ID=#{insertStd.id}, NAME=#{insertStd.name}, BRANCH=#{insertStd.branch}, PERCENTAGE=#{insertStd.percentage}, PHONE=#{insertStd.phone}, EMAIL =#{insertStd.email});
</insert>
Service call method
public boolean saveStudent(Student student){
LOGGER.info("Student object save");
int savedId= studentMapper.insertStd(student);
}
Log file
org.springframework.jdbc.badsqlgrammarexception
### Error updating database Causes: cause org.postgresql.util.psqlexception error column id does not exist
HINT: There is a column named "id" in the table "student" but it can't be referenced from this part of the query.
Position 200
### Error may exist in file [c:\.....\StudentMapper.xml]
### Error may involve in com.org.springboot.dao.StudentMapper.insertStd-InLine
### The error occurred while setting parameters
### SQL INSERT INTO STUDENT (ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL )
VALUES (ID=?, NAME=?,BRANCH=?, PERCENTAGE=?, PHONE=?, EMAIL=?);
### cause org.postgresql.util.psqlexception ERROR column "id" doesn't exist. //It did worked with JPA id assigned manually.
### There is a column named "ID" in the table "STUDENT", Bbut it cannot be referenced from the part of the query.

The INSERT statement of malformed. The VALUES clause should not include the column names.
Also, since there's no primary auto-generation, you can remove all the other attributes. Just leave the mapper id.
Note: if you want to manually assign the PK value, you need to make sure the table does not have a GENERATED ALWAYS clause for the column. If this is the case, the table will ignore the value you are providing and will use its own rules to generate the PK.
Use:
<insert id="insertStd">
INSERT INTO STUDENT (ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL)
VALUES (
#{insertStd.id}, #{insertStd.name}, #{insertStd.branch},
#{insertStd.percentage}, #{insertStd.phone}, #{insertStd.email}
);
</insert>
Your error is easily reproduceable:
create table t (a int, b varchar(10));
insert into t (a, b) values (123, 'ABC'); -- succeeds
insert into t (a, b) values (a=123, b='ABC'); -- fails!
error: column "a" does not exist
See the Fiddle.

Related

psycopg2 Ignore inserting row with null value

I'm populating a database from a .csv file and somewhere in my code I'm referring to a foreign key that might be invalid ( so when I'm going to select that id it returns null). At this point I want to log the row that returns null value and ignore insertion of that row but transaction don't stop and continue. How do I achieve this?
for index, row in df.iterrows():
insert_query = f"""insert into {table_name}
(travel_date, train_id, delay)
values ({row[0]},
(select id from {train_table} where {train_table}.train_no={row[1]} limit 1),
{row[2]});"""
cursor.execute(insert_query)

Renaming all existing attributes in an array of Json objects

I work with Postgres db.
For example - there is a table
CREATE TABLE public.json_objects(id serial primary key, objects text);
it stores such an arrays of json
INSERT INTO public.json_objects (objects) VALUES ('[{"name":"Ivan"}]'), ('[{"name":"Petr"}, "surname":"Petrov"}]'), ('[{"form":"OOO"}, {"city":"Kizema"}]');
How can I replace the attribute "name" with "first name" or "surname" with "second name" everywhere?
I am using update with the select - subquery.
In this case, a replacement will occur, but if the attribute does not exist in the json object, then it will be added to the json with a null value (and this should not be)
WITH updated_table AS (SELECT id, jsonb_agg(new_field_json) as new_fields_json
FROM (SELECT id, jsonb_array_elements(json_objects.objects::jsonb) - 'name' || jsonb_build_object('first name', jsonb_array_elements(json_objects.objects::jsonb) -> 'name') new_field_json FROM public.json_objects) r group by id) UPDATE public.json_objects SET objects = updated_table.new_fields_json FROM updated_table where json_objects.id = updated_table.id
This seems to be a single operation, so you can just use the regexp_replace function to replace the key
update table_1 set objects = regexp_replace(objects, '(\"name"+)', '"first name"');
update table_1 set objects = regexp_replace(objects, '(\"surname"+)', '"second name"')
Demo in dbfiddle

Is posible to get better error message when a domain check fail on postgresql?

I create a domain to catch empty strings:
CREATE DOMAIN TEXTN AS TEXT
CONSTRAINT non_empty CHECK (length(VALUE) > 0);
Then I replace all text/varchars fields on the DB with TEXTN.
However, when I get a error, it not give much info:
DbError { severity: "ERROR", parsed_severity: Some(Error),
code: SqlState("23514"),
message: "value for domain textn violates check constraint \"non_empty\"",
detail: None, hint: None, position: None, where_: None,
schema: Some("libs"),
table: None,
column: None, datatype: Some("textn"),
constraint: Some("non_empty")}
It not even tell me in what table and field the check fail.
If is even possible to print the row to insert better, but at least table and field is possible?
PostgreSQL (I checked version 11) simply does not provide this information as part of the protocol. Consider these statements:
=> CREATE DOMAIN TEXTN AS TEXT CONSTRAINT non_empty CHECK (length(VALUE) > 0);
CREATE DOMAIN
=> CREATE TABLE test_table (test_column textn);
CREATE TABLE
=> INSERT INTO test_table VALUES ('');
ERROR: value for domain textn violates check constraint "non_empty"
The error message on the wire looks like this:
S ERROR
V ERROR
C 23514
M value for domain textn violates check constraint "non_empty\
s public
d textn
n non_empty
F execExprInterp.c
L 3494
R ExecEvalConstraintCheck
There is no trace of test_table or test_column.
If you have some control over how your framework creates tables, it may be possible to use named table constraints instead of domain types, like this:
CREATE TABLE test_table (
test_column text
CONSTRAINT test_column_check CHECK (length(test_column) > 0));
If you make sure that the constraint name uniquely identifies the column, you can use that to recover the problematic column.
Even for a CHECK constraint defined on the column, as in CREATE TABLE test_table (test_column text CHECK (length(test_column) > 0));, PostgreSQL does not report the column name. You only get the name of the constraint, which is autogenerated by PostgreSQL on table creation and usually starts with the column name, but this is not guaranteed.

Why postgresql encount duplicate key when key not exists?

When I am inserting data into Postgresql(9.6),throw this error:
ERROR: duplicate key value violates unique constraint "book_intial_name_isbn_isbn10_key"
DETAIL: Key (name, isbn, isbn10)=(三銃士, , ) already exists.
SQL state: 23505
I add uniq constraint on columns name, isbn, isbn10.But when I check the distination table,it does not contains the record:
select * from public.book where name like '%三銃%';
How to fix?This is my insert sql:
insert into public.book
select *
from public.book_backup20190405 legacy
where legacy."name" not in
(
select name
from public.book
)
limit 1000
An educated guess, there may be more than one row in the source table book_backup20190405 which has the unique key tuple ('三銃', '', '').
Since the bulk INSERT INTO ... SELECT ... will be be transactional, you'll be none the wiser to the error, since all data will have been rolled back when the constraint fails.
You can verify this by running a dupe check on the source table:
SELECT name, isbn, isbn10, COUNT(*)
FROM public.book_backup20190405
WHERE name = '三銃'
GROUP BY name, isbn, isbn10
HAVING COUNT(*) > 1;
To see if there are duplicates.
Here's an example of how the source table can be the sole source of duplicates:
http://sqlfiddle.com/#!17/29ba3

How to insert DB Default values under EF?

when adding a new record like this
ContentContacts c2 = new ContentContacts();
c2.updated_user = c2.created_user = loggedUserId;
c2.created_date = c2.updated_date = DateTime.UtcNow;
db.ContentContacts.AddObject(c2);
I'm getting
Cannot insert the value NULL into column 'main_email_support', table 'SQL2008R2.dbo.ContentContacts'; column does not allow nulls. INSERT fails. The statement has been terminated.
but the default value in the database is an empty string like:
why am I getting such error? shouldn't the EF says something like:
"ohh, it's a nullvalue, so let's add the column default value instead"
I did a small test, created a table with a column that had a default value but did not allow nulls.
Then this SQL Statement:
INSERT INTO [Test].[dbo].[Table_1]
([TestText])
VALUES
(null)
Gives this error:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'TestText', table
'Test.dbo.Table_1'; column does not allow nulls. INSERT fails.
The problem here is that the insert specifies all the columns, also those with default values. The the Insert tries to update the columns with null values.
You have 2 options:
Update the table through a view, which does not contain the default columns
Set the default values in your C# code
A default value is business logic, so there is a case for it being set in the business layer of your application.