Insert some variable columns with constants - sql

What I'm looking to do with my code is insert some variable number of rows into test_table where 'policy' in source_table matches 'bond_ser' in policy_custsgt and 'SNL_ID' in source_table matches 'inst_key' in raw_table.
I want it to insert serial_number and ID along with some other constants. I can get it to insert serial_number and ID just fine, but how do I get it to add some constants in other fields of the table every time it inserts the variables from the other tables?
This is the code I currently have, if I remove the "'122812', '999999', 'myname'" from the first line it works fine but will only populate the serial_number and ID columns of my table with each insert.
INSERT INTO test_table(serial_number, ID, '122812', '999999', 'myname')
SELECT policy, SNL_ID
FROM source_table
WHERE (policy IN (SELECT bond_ser from policy_custsgt)) AND
(SNL_ID in (select inst_key from raw_table))
Thanks!

Of course, I over looked the simple solution. All I needed to do was move those constants I wanted down from the INSERT statement to the SELECT statment, and add the column names in the INSERT so:
INSERT INTO test_table(serial_number, ID, starting_date, ending_date, user_id)
SELECT policy, SNL_ID, '122812', '999999', 'myname'
FROM source_table
WHERE (policy IN (SELECT bond_ser from policy_custsgt)) AND
(SNL_ID in (select inst_key from raw_table))

Related

Inserting data into a table(mutliple columns) which has primary key from another data which has data except primary key

I have a table that has 3 columns ID(Primary Key), Name, City.
I need to import data from another table that has only Name and City.
I can write insert into table 1(Name, City) select Name, City from table2.
But then I need ID in table 1 which needs to be inserted using a sequence.
I tried this:
insert into table1(ID, Name,City) values(seq.nextval, select distinct name, city from table2). But I am receiving an error saying an insufficient number of values.
I am trying it in SQL Oracle. Can someone please help me with this?
You are mixing the insert ... values and insert ... select syntax.
You edited your question to include distinct, implying you have duplicate name/city pairs that you want to suppress; but neither version gets the error you reported. If you don't have duplicates then you can just do:
insert into table1(ID, Name,City)
select seq.nextval, name, city from table2;
If you do have duplicates then you can't just add the distinct keyword, but you can use a subquery:
insert into table1 (id, name, city)
select seq.nextval, name, city
from (
select distinct name, city
from table2
);
db<>fiddle
You could also set the ID via a trigger. If you we're on a recent version you could use an identity column instead - but you tagged the question with Oracle 11g, where those are not available.

Will order by preserve?

create table source_table (id number);
insert into source_table values(3);
insert into source_table values(1);
insert into source_table values(2);
create table target_table (id number, seq_val number);
create sequence example_sequence;
insert into target_table
select id, example_sequence.nextval
from
> (select id from source_table ***order by id***);
Is it officially assured that for the id's with the lower values in source_table corresponding sequence's value will also be lower when inserting into the source_table? In other words, is it guaranteed that the sorting provided by order by clause will be preserved when inserting?
EDIT
The question is not: 'Are rows ordered in a table as such?' but rather 'Can we rely on the order by clause used in the subquery when inserting?'.
To even more closely illustrate this, the contents of the target table in the above example, after running the query like select * from target_table order by id would be:
ID | SEQ_VAL
1 1
2 2
3 3
Moreover, if i specified descending ordering when inserting like this:
insert into target_table
select id, example_sequence.nextval
from
> (select id from source_table ***order by id DESC***);
The output of the same query from above would be:
ID | SEQ_VAL
1 3
2 2
3 1
Of that I'm sure, I have tested it multiple times. My question is 'Can I always rely on this ordering?'
Tables in a relational database are not ordered, and any apparent ordering in the result set of a cursor which lacks an ORDER BY is an artifact of data storage, is not guaranteed, and later actions on the table may cause this apparent ordering to change. If you want the results of a cursor to be ordered in a particular manner you MUST use an ORDER BY.

Insert a new record with a field containing total record in the table

I wonder if it exists a function that allows me to get total rec count of a table to for new record insertion into the table?
I have this table:
CREATE TABLE "TEST"
( "NAME" VARCHAR2(20 BYTE),
"ID" NUMBER,
"FLAG" NUMBER
) ;
Insert into TEST (NAME,ID,FLAG) values ('Ahlahslfh',1,1);
Insert into TEST (NAME,ID, FLAG) values ('Buoiuop',2,1);
Insert into TEST (NAME,ID, FLAG) values ('UOIP',12,0);
My intention is to issue a statement that is equivalent to this:
INSERT INTO TEST( NAME, ID, FLAG )
VALUES( 'TST', 3,1 );
The statement I used below generated error:
INSERT INTO TEST ( NAME, ID, FLAG )
VALUES ( 'TST', SELECT COUNT(*)+1 FROM TEST WHERE FLAG=1,1 );
Below is the final result I am expecting:
Is there a way around it? Of course, I can put them in a script, count the records into a variable and insert that variable into the field. I just wonder if there is more elegant solution and do this in 1 statement.
Thanks!
This is likely to be a very bad way to set an id. In general, I think you should use sequences/identity/auto_increment and not worry about gaps.
But, you can do what you want using parentheses -- these are needed for subqueries:
INSERT INTO TEST(NAME, ID, FLAG)
VALUES ('TST',
(SELECT COUNT(*)+1 FROM TEST WHERE FLAG = 1),
1
);
Or, alternatively:
INSERT INTO TEST(NAME, ID, FLAG)
SELECT 'TST', COUNT(*) + 1, 1
FROM TEST
WHERE FLAG = 1;
I must emphasize that this seems dangerous. It is quite possible that you will get duplicate ids. You should really let the database insert a new value and not worry about gaps.

Insert output IDs into another table

I have a status table, and another table containing additional data. My object IDs are the PK in the status table, so I need to insert those into the additional data table for each new row.
I need to insert a new row into my statusTable for each new listing, containing just constants.
declare #temp TABLE(listingID int)
insert into statusTable(status, date)
output Inserted.listingID into #temp
select 1, getdate()
from anotherImportedTable
This gets me enough new listing IDs to use.
I now need to insert the actual listing data into another table, and map each row to one of those listingIDs -
insert into listingExtraData(listingID, data)
select t.listingID, a.data
from #temp t, anotherImportedTable a
Now this obviously doesn't work, because otherDataTable and the IDs in #temp are unrelated... so I get far too many rows inserted.
How can I insert each row from anotherImportedTable into listingExtraData along with a unique newly created listingID? could I possibly trigger some more sql at the point I do the output in the first block of sql?
edit: thanks for the input so far, here's what the tables look like:
anotherImportedTable:
data
statusTable:
listingID (pk), status, date
listingExtraData:
data, listingID
You see that I only want to create one entry into statusTable per row in anotherImportedTable, then put one listingID with a row from anotherImportedTable into listingExtraData... I'm thinking that I might have to resort to a cursor perhaps?
Ok, here's how you can do it (if I'm right about what you actually want to do):
insert into listingExtraData(listingID, data)
select q1.listingID, q2.data
from
(select ListingID, ROW_NUMBER() OVER (order by ListingID) as rn from #temp t) as q1
inner join (select data, ROW_NUMBER() over (order by data) as rn from anotherImportedTable) q2 on q1.rn = q2.rn
In case you matching logic differs you will need to change sorting of anotherImportedTable. In case your match order can not be achieved by ordering anotherImportTable [in one way or another] then you're out of luck.

Insert into select and update in single query

I have 4 tables: tempTBL, linksTBL and categoryTBL, extra
on my tempTBL I have: ID, name, url, cat, isinserted columns
on my linksTBL I have: ID, name, alias columns
on my categoryTBL I have: cl_id, link_id,cat_id
on my extraTBL I have: id, link_id, value
How do I do a single query to select from tempTBL all items where isinsrted = 0 then insert them to linksTBL and for each record inserted, pickup ID (which is primary) and then insert that ID to categoryTBL with cat_id = 88. after that insert extraTBL ID for link_id and url for value.
I know this is so confusing, put I'll post this anyhow...
This is what I have so far:
INSERT IGNORE INTO linksTBL (link_id,link_name,alias)
VALUES(NULL,'tex2','hello'); # generate ID by inserting NULL
INSERT INTO categoryTBL (link_id,cat_id)
VALUES(LAST_INSERT_ID(),'88'); # use ID in second table
I would like to add here somewhere that it only selects items where isinserted = 0 and iserts those records, and onse inserted, will change isinserted to 1, so when next time it runs, it will not add them again.
As longneck said, you cannot do multiple things in one query, but you can in a stored procedure.
http://dev.mysql.com/doc/refman/5.1/en/insert-select.html
INSERT INTO linksTBL (link_id,link_name,alias)
SELECT field1, field2, field3
FROM othertable
WHERE inserted=0;
this is not possible to do in a single query. you will have to insert the rows, then run a separate update statement.