I am trying to create a calculation logic using MySQL tables.
Data from two table is processed using a stored procedure and a set of values is generated.
These values are part of a column of output table.
I have to run different procedure to generate output for each column in output table
Now if I create insert query for each row it will have large number of inserts for each column. Can I insert a set of values into a table column in one go? assuming other columns can be NULL.
INSERT INTO tableName(columnName)
VALUES ('baz'),('foo'),('bar'),('baz'),('baz'),('baz'),('baz');
etc as u like..
See this: Bulk insert into table with one single query
The insert can be done for one column rest can be NULL if remaining columns are nullable.
But next time for the remaining columns the Insert will not work for the existing rows. If You want to update the existing rows then you need to fire the update query.
Assuming col1 and col2 are nullable
If you want to insert in col1 keeping col2 null insert will work
If you want to insert in col2 keeping col1 null insert will work
Related
I want to insert multiple rows into a table, using a single INSERT statement. This is no problem, since SQL offers the option to provide multiple rows as parameter for a single INSERT statement. Now, those rows contain an ID field that is incremented automatically, i.e. its value is set by the database, not by my code.
As a result, I would like to get the ID values of the inserted rows. My basic question is: How do I do that for MariaDB / MySQL?
As it turns out, this is pretty simple, e.g. in PostgreSQL, as PostgreSQL has the RETURNING clause for INSERT which returns the desired values for one or even for multiple rows. This is exactly what I want and it works.
Unfortunately, neither MariaDB nor MySQL have PostgreSQL's RETURNING clause, so I need to fallback to something such as LAST_INSERT_ID(), but this only returns the ID of the single last inserted row, even if multiple rows were inserted using a single INSERT. How do I get all the ID values?
My code currently looks like this:
INSERT INTO mytable
(foo, bar)
VALUES
('fooA', 'barA'),
('fooB', 'barB');
SELECT LAST_INSERT_ID() AS id;
How can I solve this issue in a way that works even with concurrent writes?
(And no, it's not an option to change to a UUID field, or something like this; the auto-increment field is given, and can not be changed.)
MySQL & MariaDB have the LAST_INSERT_ID() function, and it returns the id generated by the most recent INSERT statement in your current session.
But when your INSERT statement inserts multiple rows, LAST_INSERT_ID() returns the first id in the set generated.
In such a batch of multiple rows, you can rely on the subsequent id's being consecutive. The MySQL JDBC driver depends on this, for example.
If the rows you insert include a mix of NULL and non-NULL values for the id column, you have a risk of messing up this assumption. The JDBC driver returns the wrong values for the set of generated id's.
As stated in the comments, you can capture the inserted IDs (SQL Server):
use tempdb
create table test (
id int identity(1,1) primary key,
t varchar(10) null
)
create table ids (
i int not null
)
insert test(t)
output inserted.id into ids
values (null), (null), (null)
select *
from test
select *
from ids
How can I INSERT values to two tables using only one query? I am using MySQL. One of the tables I want to insert to is a many-to-many relationship table. Please see my example below:
I recently added the many-to-many relationship tables. When I insert on the news, I type the following script:
INSERT INTO news (title, reporter_id)
VALUES ('Some Title', 15);
How can I have one query an be able to insert to two tables? Per MySQL insert documentation, seems like I can do query like
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
The problem is, I dont know my news_id until I execute my first insert. Should I just have two insert statements or is there a better way? Thanks for your help!
As mentioned by Uueerdo in the comments, you can use an AFTER INSERT trigger and access the generated ID with NEW.id. However - if you want to keep that logic in your application layer, you can copy the data from the first table to the second after your bulk insert with:
start transaction;
insert into news(title, reporter_id) values
('title2', 2),
('title3', 3);
insert into junctions(news_id, reporter_id)
select id, reporter_id
from news
where id >= last_insert_id()
order by id asc
limit 2;
commit;
This works for InnoDB if the innodb_autoinc_lock_mode is set to 0 or 1, because the generated IDs are guaranteed to be consecutive.
With innodb_autoinc_lock_mode set to 0 (“traditional”) or 1 (“consecutive”), the auto-increment values generated by any given statement are consecutive, without gaps, because the table-level AUTO-INC lock is held until the end of the statement, and only one such statement can execute at a time.
AUTO_INCREMENT Handling in InnoDB
LAST_INSERT_ID() will return the generated ID of the first inserted row.
If you insert multiple rows using a single INSERT statement, LAST_INSERT_ID() returns the value generated for the first inserted row only.
Information Functions - LAST_INSERT_ID()
You know the first generated ID. You know the number of inserted rows. So you know which rows to copy.
Demo: http://rextester.com/UEN69961
I am using MYSQL in my application development as my DB.
I want to clarify a thing.
Imagine There is a table called test.
Columns are col1,col2,col3,col4.
these columns have separate indexes. that mean 4 indexes.
I am inserting a record just to col1 and col2.
When you have a index in a column insert operation have a cost.
My question is. ----
So when I insert records only to one and two Do I have an affect from col3 and col4 ?
Will indexes will fire for every insert or will it fire if I do insert to those columns?
Let's get a basic fact straight: in an RDBMS there is no such thing that you insert a record for only a selected number fields in a table. If you insert a record, then all fields within that table will have a value for that record. That value may be a null value, but it is there.
Not to mention another fact, that columns may have non-null default values, so executing an insert that does not specify value for them will still result a non-null value to be stored.
Mysql indexes even null values, so if you have separate indexes for each column, then mysql has to update all indexes when a new record is inserted into the table, regardless how many fields are specifically assigned value within the insert.
I have a table that has a number of columns. For each row, I'd like to select three columns (PAR_BOOK, PAR_PAGE, PAR_LINE) and concatenate the contents of those three columns into a new fourth column (APN).
So, if PAR_BOOK=0108, PAR_PAGE=291 and PAR_LINE=07, APN should be 010829107
Make sense?
But, I'm unsure of what query I should use to do this. I need the results stored back in the same table as it needs to be ultimately exported out as a csv to work with the program that's going to map the data.
Assuming your fourth column is already in the table, you would use the following update query:
UPDATE YourTable
SET APN = CONCAT(PAR_BOOK, PAR_PAGE, PAR_LINE)
If your fourth column is not present in the table yet, you should use the ALTER TABLE statement to add it first before running the UPDATE statement:
ALTER TABLE YourTable
ADD APN VARCHAR(256) NULL
Inserting into the same table with INSERT INTO ... SELECT ... is no problem at all. MySQL holds the selected rows in a temporary table.
what if I wanted to update the records in the table by altering values in one of the columns?
I have records in the table that have one column empty(null values). I want to change these values and insert values from another table into those records.
Basically I have a table with one column empty. I do not want to append to the end of the table but start inserting from record 1.
For the existing records, you would have to use UPDATE to update that one column, WHERE thatColumn IS NULL.
Shouldn't the values in that column have some relation to the rest of the record? I could understand initializing the existing records to a non-null value, or using an UPDATE query to populate data from another table in that column, but all related to the original row...
UPDATE old SET old.badColumn = new.newData
FROM oldTable old
JOIN newTable new on old.someID = new.someID
This would find the related data in newTable matching oldTable, and update the badColumn to some data from newTable... let me know if you need more help.
See the "Using the UPDATE statement with information from another table" section from this page of SQL Server Books Online.