I am executing the following query, but it is inserting partial value of first field, i.e 95362 instead of 95362-07
Insertion query::
INSERT INTO ACCIDENT VALUES(95362-07,'Orthoptic education on visual ergonomics','Orthoptic education on visual ergonomics');
Getting values in the table ::
95362,Orthoptic education on visual ergonomics,Orthoptic education on visual ergonomics.
Table structure:
desc accident
Name Null Type
--------------------------------------------------
ID NUMBER
ACC_NAME VARCHAR2(4000)
ACC_DESC VARCHAR2(4000)
Here's the problem, your first column is expecting a data type of Number
desc accident
Name Null Type
--------------------------------------------------
ID NUMBER
ACC_NAME VARCHAR2(4000)
ACC_DESC VARCHAR2(4000)
And then, when you insert your query, the first parameter is being computed only the NUMBER part of it, which is 95362.
To store your ID records in the form XXXXX-XX you must change your ID column to a VARCHAR2 data type. Otherwise you'll keep getting this result.
I hope it helped. Cheers
Related
I have a requirement where I need to generate an account number and insert it into a table column in the following format.
"TBA2222011300000001" = where "TBA" is the value of another column or user sent data "22220113" implies the current date and "00000001" is a seven digit sequence that needs to be incremented and appended for every insert.
How can I append the sequence to the column, Should I do it in java or can it be done at DB end. I am currently using postgres with java and spring boot.
https://www.postgresql.org/docs/current/ddl-generated-columns.html
A generated column is a special column that is always computed from
other columns.
Several restrictions apply to the definition of
generated columns and tables involving generated columns:
The generation expression can only use immutable functions and cannot use subqueries or reference anything other than the current row
in any way.
now() is mutable function, so you cannot use Generated columns.
I am not sure why Default not working.
https://www.postgresql.org/docs/current/ddl-default.html
So now the only option is trigger.
CREATE TABLE account_info(
account_id INT GENERATED ALWAYS AS IDENTITY,
account_type text not null,
acconut_number text ) ;
So what you want is to automate:
UPDATE account_info set
account_number =
concat(
account_type,
to_char(CURRENT_DATE, 'yyyymmdd'),
to_char(account_id, 'FM00000000'));
create the function
create or replace function update_account_number() returns trigger as $$
BEGIN
UPDATE account_info set
account_number =
concat(
account_type,
to_char(CURRENT_DATE, 'yyyymmdd'),
to_char(account_id, 'FM00000000'));
RETURN NULL;
end;
$$ LANGUAGE plpgSQL;
create the trigger:
CREATE OR REPLACE TRIGGER udpate_accout_number
AFTER INSERT ON account_info
FOR EACH ROW
EXECUTE FUNCTION update_account_number();
Have an id column which is identity in postgres with start and end index as required.
For your reference to create identity column as desired
https://www.postgresqltutorial.com/postgresql-identity-column/
Have 1 more column for createdDate.
Then account number is simply a derived value TBA + formatted(DATE) + formatted(Id).
Ex -
No not a trigger just a function. There won't be any account number column in your table. It will simply be a function which takes date and identity as input and gives account number as output. Since account number is only dependent on id and date. No need to store this value at all, whenever you need the account number just call that function. Account number will not exist at all. It will always be calculated based on id and date. Simple.
Refer this in the article
Method 1: Derived Value called "markup"
The first method we may want to add to this table is a accountNumber method, for calculating our accountNumber based on current date and id. Since this value will always be based on two other stored values, there is no sense in storing it (other than possibly in a pre-calculated index). To do this, we:
CREATE FUNCTION accountNumber(id,date) RETURNS varchar AS
$$ SELECT TBA + format(id) + format(date)
$$ LANGUAGE SQL IMMUTABLE;
You need to put logic for format(id) and format(date) as per your requirement.
There is no point of storing the value which can be easily derived from other 2 columns. It would unnecessary consume space. Also maintaining data integrity and checks will be an overhead.
Creating function for derived values
https://ledgersmbdev.blogspot.com/2012/08/postgresql-or-modelling-part-2-intro-to.html
You can use the function in output as well as search.
Index would also be utilized as required.
I did the following to generate the desired account number.
Created a new sequence and appended zeros to it.
select to_char(nextval('finance_accounts_id_seq'), 'fm00000000')
Got the Current date in java using DateTimeFormatter
DateTimeFormatter dmf = DateTimeFormatter.ofPattern("yyyyMMdd");
String date = LocalDate.now().format(dmf);
Got the "TBA" from request param of the user.
I am running into the issue where I am making a query from one table and trying to map and store the results it returns into another table. There is one field in my new table that's unique to that table while the other values being mapped have the same name from the original mapped table. Now the problem I have is that hibernate is saying that a unique field is not part of the result set so it can't map it. What can I do to let hibernate know that this field is only part of the new table and not part of the table it' gets mapped from?
Table A
name
age
Table B
name
age
height
#Query(
value = "select name, age, from table A group by (name, age)",
nativeQuery = true
)
List<TableB> mapData();
Hiberate Returns
The column name height was not found in this ResultSet.
I must remind you that such a return value can easily break the code design. For query operations on the same data table, the best option is to return the same pojo.
If you need to convert TableA to TableB in other logic, maybe you can search for "java object copy", for example: http://dozer.sourceforge.net/
I'm trying to make a blog system of sort and I ran into a slight problem.
Simply put, there's 3 columns in my article table:
id SERIAL,
category VARCHAR FK,
category_id INT
id column is obviously the PK and it is used as a global identifier for all articles.
category column is well .. category.
category_id is used as a UNIQUE ID within a category so currently there is a UNIQUE(category, category_id) constraint in place.
However, I also want for category_id to auto-increment.
I want it so that every time I execute a query like
INSERT INTO article(category) VALUES ('stackoverflow');
I want the category_id column to be automatically be filled according to the latest category_id of the 'stackoverflow' category.
Achieving this in my logic code is quite easy. I just select latest num and insert +1 of that but that involves two separate queries.
I am looking for a SQL solution that can do all this in one query.
This has been asked many times and the general idea is bound to fail in a multi-user environment - and a blog system sounds like exactly such a case.
So the best answer is: Don't. Consider a different approach.
Drop the column category_id completely from your table - it does not store any information the other two columns (id, category) wouldn't store already.
Your id is a serial column and already auto-increments in a reliable fashion.
Auto increment SQL function
If you need some kind of category_id without gaps per category, generate it on the fly with row_number():
Serial numbers per group of rows for compound key
Concept
There are at least several ways to approach this. First one that comes to my mind:
Assign a value for category_id column inside a trigger executed for each row, by overwriting the input value from INSERT statement.
Action
Here's the SQL Fiddle to see the code in action
For a simple test, I'm creating article table holding categories and their id's that should be unique for each category. I have omitted constraint creation - that's not relevant to present the point.
create table article ( id serial, category varchar, category_id int )
Inserting some values for two distinct categories using generate_series() function to have an auto-increment already in place.
insert into article(category, category_id)
select 'stackoverflow', i from generate_series(1,1) i
union all
select 'stackexchange', i from generate_series(1,3) i
Creating a trigger function, that would select MAX(category_id) and increment its value by 1 for a category we're inserting a row with and then overwrite the value right before moving on with the actual INSERT to table (BEFORE INSERT trigger takes care of that).
CREATE OR REPLACE FUNCTION category_increment()
RETURNS trigger
LANGUAGE plpgsql
AS
$$
DECLARE
v_category_inc int := 0;
BEGIN
SELECT MAX(category_id) + 1 INTO v_category_inc FROM article WHERE category = NEW.category;
IF v_category_inc is null THEN
NEW.category_id := 1;
ELSE
NEW.category_id := v_category_inc;
END IF;
RETURN NEW;
END;
$$
Using the function as a trigger.
CREATE TRIGGER trg_category_increment
BEFORE INSERT ON article
FOR EACH ROW EXECUTE PROCEDURE category_increment()
Inserting some more values (post trigger appliance) for already existing categories and non-existing ones.
INSERT INTO article(category) VALUES
('stackoverflow'),
('stackexchange'),
('nonexisting');
Query used to select data:
select category, category_id From article order by 1,2
Result for initial inserts:
category category_id
stackexchange 1
stackexchange 2
stackexchange 3
stackoverflow 1
Result after final inserts:
category category_id
nonexisting 1
stackexchange 1
stackexchange 2
stackexchange 3
stackexchange 4
stackoverflow 1
stackoverflow 2
Postgresql uses sequences to achieve this; it's a different approach from what you are used to in MySQL. Take a look at http://www.postgresql.org/docs/current/static/sql-createsequence.html for complete reference.
Basically you create a sequence (a database object) by:
CREATE SEQUENCE serials;
And then when you want to add to your table you will have:
INSERT INTO mytable (name, id) VALUES ('The Name', NEXTVAL('serials')
so I created a table with a column which I declared EmployeeID as a primary key int with auto increment, but here is the problem:
If I delete a row and then insert a new one the new increment will still count
For example:
ID Name
1 jayden
2 karen
delete karen ...
ID Name
1 jayden
insert new one
ID Name
1 jayden
3 nicolas
So it basically skips the previous ID.
This is not a mistake, it is how MySQL works with auto_increment. It stores the last value which it gave at the insertion and increments it. You can always get the last ID at your next insertion
insert into yourtable(id, Name)
select id + 1, 'foo'
from yourtable
where id = (select max(id) from yourtable);
That's because an auto increment is a independent property of your table, that is only used when assigning new IDs and does not depend on the last existent ID on your table. This is how many relational databases, not only MySQL, were designed for.
To achieve what you want (which seems to be having IDs in sequence without "holes") you would need to query the last ID and increment on it to be set manually.
Ex:
SELECT id from Users ORDER BY id DESC LIMIT 1
Or instead setting the auto_increment of your table according to your last id.
Be aware that both of this is not performatically wise. You should really stick to the auto increment default behavior, since it's optimal, unless you have some strong reason for not doing things as they were designed to be done.
This is expected behavior from the 'delete' command
What would you ever want/need an Unique Identifier that can be reaffected to someone else?
The 'Truncate' command will delete all your data and reset the ID, maybe this is what you are looking for
After delete a row use this query,
ALTER TABLE tbl_name AUTO_INCREMENT = ID;
Actually this is how MySQL works and it's not a mistake
In my java web application, I am inserting some records into MySql db. I have a column name 'value' whose Field type is float. When I insert the following value 76.8653846153846 into db, it gives exception of Data truncated for column 'value' at row 1. I changed field type to Double but same message. Any idea?
Field description:
As per the documentation you must define your number type with the level of precision you require.
for your number 76.8653846153846 use
FLOAT(10,13)
The 13 being large enough to handle your .8653846153846
[Edit]
to alter your existing table execute this command substituting your table and column name for mytable and mycolumn respectively
ALTER TABLE mytable MODIFY mycolumn FLOAT(10,13)
This comes from the database engine where the declared field's description in the table is not big enough to insert the complete data