Need Help using a loop to perform a mass insert in SQL - sql

First off, i should say up front that i am not a very strong SQL person, so please be gentle :)
I need to perform about 400 inserts into a particular table. The data that i will be using for these inserts, i can collect from a SELECT statement that runs off a different table. I only need the data from 1 column from this table.
So, im hoping someone can help me write the SQL that will basically take the list of id's that are returned from my select, and use that list to do a mass insert into another table.
In psuedocode, something like this:
Select BankID from BankTable; - this returns 300 rows
Insert Into AccountTable -- this will add all 300 rows into the 2nd table
Values
(BankID)
thanks in advance guys...

Very simple, you basically said it. :-)
INSERT Into AccountTable (BankId, SecondColumn) SELECT BankId,'XXX' as staticText FROM BankTable;

It can be done in one statement:
Insert Into AccountTable (bankid)
Select BankID from BankTable
This assumes that the column in AccountTable is also named bankid; if not, just set the name appropriately in the parenthesis.

Keep in mind your INSERT statement must include the columns if the select statement does not match your table definition precisely.
INSERT AccountTable (BankID)
SELECT BankID
FROM BankTable
For multiple columns simply include the column list:
INSERT AccountTable (BankID, BankName)
SELECT BankID, BankName
FROM BankTable
You can also run into type conversion issues if the data types of the columns don't match (i.e. integer fields won't take alpha characters, etc.), but it is not a necessity that the column names match. Just get the order of columns and types right and you should be good.

Related

Does Oracle allow an SQL INSERT INTO using a SELECT statement for VALUES if the destination table has an GENERATE ALWAYS AS IDENTITY COLUMN

I am trying to insert rows into an Oracle 19c table that we recently added a GENERATED ALWAYS AS IDENTITY column (column name is "ID"). The column should auto-increment and not need to be specified explicitly in an INSERT statement. Typical INSERT statements work - i.e. INSERT INTO table_name (field1,field2) VALUES ('f1', 'f2'). (merely an example). The ID field increments when typical INSERT is executed. But the query below, that was working before the addition of the IDENTITY COLUMN, is now not working and returning the error: ORA-00947: not enough values.
The field counts are identical with the exception of not including the new ID IDENTITY field, which I am expecting to auto-increment. Is this statement not allowed with an IDENTITY column?
Is the INSERT INTO statement, using a SELECT from another table, not allowing this and producing the error?
INSERT INTO T.AUDIT
(SELECT r.IDENTIFIER, r.SERIAL, r.NODE, r.NODEALIAS, r.MANAGER, r.AGENT, r.ALERTGROUP,
r.ALERTKEY, r.SEVERITY, r.SUMMARY, r.LASTMODIFIED, r.FIRSTOCCURRENCE, r.LASTOCCURRENCE,
r.POLL, r.TYPE, r.TALLY, r.CLASS, r.LOCATION, r.OWNERUID, r.OWNERGID, r.ACKNOWLEDGED,
r.EVENTID, r.DELETEDAT, r.ORIGINALSEVERITY, r.CATEGORY, r.SITEID, r.SITENAME, r.DURATION,
r.ACTIVECLEARCHANGE, r.NETWORK, r.EXTENDEDATTR, r.SERVERNAME, r.SERVERSERIAL, r.PROBESUBSECONDID
FROM R.STATUS r
JOIN
(SELECT SERVERSERIAL, MAX(LASTOCCURRENCE) as maxlast
FROM T.AUDIT
GROUP BY SERVERSERIAL) gla
ON r.SERVERSERIAL = gla.SERVERSERIAL
WHERE (r.LASTOCCURRENCE > SYSDATE - (1/1440)*5 AND gla.maxlast < r.LASTOCCURRENCE)
) )
Thanks for any help.
Yes, it does; your example insert
INSERT INTO table_name (field1,field2) VALUES ('f1', 'f2')
would also work as
INSERT INTO table_name (field1,field2) SELECT 'f1', 'f2' FROM DUAL
db<>fiddle demo
Your problematic real insert statement is not specifying the target column list, so when it used to work it was relying on the columns in the table (and their data types) matching the results of the query. (This is similar to relying on select *, and potentially problematic for some of the same reasons.)
Your query selects 34 values, so your table had 34 columns. You have now added a 35th column to the table, your new ID column. You know that you don't want to insert directly into that column, but in general Oracle doesn't, at least at the point it's comparing the query with the table columns. The table has 35 columns, so as you haven't said otherwise as part of the statement, it is expecting 35 values in the select list.
There's no way for Oracle to know which of the 35 columns you're skipping. Arguably it could guess based on the identity column, but that would be more work and inconsistent, and it's not unreasonable for it to insist you do the work to make sure it's right. It's expecting 35 values, it sees 34, so it throws an error saying there are not enough values - which is true.
Your question sort of implies you think Oracle might be doing something special to prevent the insert ... select ... syntax if there is an identity column, but in facts it's the opposite - it isn't doing anything special, and it's reporting the column/value count mismatch as it usually would.
So, you have to list the columns you are populating - you can't automatically skip one. So you statement needs to be:
INSERT INTO T.AUDIT (IDENTIFIER, SERIAL, NODE, ..., PROBESUBSECONDID)
SELECT r.IDENTIFIER, r.SERIAL, r.NODE, ..., r.PROBESUBSECONDID
FROM ...
using the actual column names of course if they differ from the query column names.
If you can't change that insert statement then you could make the ID column invisible; but then you would have to specify it explicitly in queries, as select * won't see it - but then you shouldn't rely on * anyway.
db<>fiddle

Common methods for doing select with computation by need?

I would like to be able to add columns to a table with cells who's values are computed by need at 'querytime' when (possibly) selecting over them.
Are there some established ways of doing this?
EDIT: Okay I can do without the 'add columns'. What I want is to make a select query which searches some (if they exist) rows with all needed values computed (some function) and also fills in some of the rows which does not have all needed values computed. So each query would do it's part in extending the data a bit.
(Some columns would start out as null values or similar)
I guess I'll do the extending part first and the query after
You use select expression, especially if you don't plan to store the calculation results, or they are dependant on more than one table. An example, as simple as it could be:
SELECT id, (id+1) as next_id FROM table;
What type of database are you asking for? If it is SQL Server then you can use the computed columns by using the AS syntax.
Eg:
create table Test
(
Id int identity(1,1),
col1 varchar(2) default 'NO',
col2 as col1 + ' - Why?'
)
go
insert into Test
default values
go
select * from Test
drop table Test
In the SQL world it's usually expensive to add a column to an existing table so I'd advise against it. Maybe you can manage with something like this:
SELECT OrderID,
ProductID,
UnitPrice*Quantity AS "Regular Price",
UnitPrice*Quantity-UnitPrice*Quantity*Discount AS "Price After Discount"
FROM order_details;
If you really insist on adding a new column, you could go for something like (not tested):
ALTER TABLE order_details ADD column_name datatype
UPDATE order_details SET column_name = UnitPrice+1
You basically ALTER TABLE to add the new column, then perform an UPDATE operation on all the table to set the value of the newly added column.

INSERT into table without specifying Column names

I have INVOICE TABLE
I want to insert value by not specifying column names
using SQL Server, I have tried this but it is not working..please help
INSERT INTO INVOICE
VALUES( 1,1,KEYBOARD,1,15,5,75)
As long as you have the right number of columns in your INSERT statement, and as long as all the values except KEYBOARD are some numeric data type, and as long as you have suitable permissions, this should work.
INSERT INTO INVOICE VALUES( 1,1,'KEYBOARD',1,15,5,75);
SQL requires single quotes around text values.
But not using column names isn't a good practice. It's not unheard of for people to change the order of columns in a table. Changing the order of columns isn't a good practice, either, but some people insist on doing it anyway.
If somebody does that, and swaps the 5th and 7th columns in your table, your INSERT statement will still succeed--both those columns are numeric--but the INSERT will screw up your data.
Why would you want to do this? Not specifying column names is bad coding practice.
In your case, though, keyboard needs to be surrounded by single quotes:
INSERT INTO INVOICE VALUES( 1,1, 'KEYBOARD',1,15,5,75)
If you just don't want to type the column names, you can get them easily in SQL Server Management Studio. Open the "Object Browser", open the database, and choose "Tables". Choose the Invoice table. One of the options is "Columns".
Just click on the "Columns" name (no need to open it) and drag it into a query window. It will insert the list of columns.
yes you can directly insert values into table as follows:
insert into `schema`.`tablename` values(val1,val2,val3);
INSERT INTO INVOICE VALUES( 1,1,'KEYBOARD',1,15,5,75);
you forget to include the single quotes in keyboard,text required single quotes in sql

Use INSERT-OUTPUT to provide values for another INSERT

Good day,
I was wondering if it is possible to use an INSERT-OUTPUT statement in such a way as to provide the value(s) for another, outer, INSERT statement. That way values can be added to an entity table and an intersection table in a single statement - I hope I'm wording this effectively. For example:
INSERT INTO [#tblIntersect] ([Entity1ID], [Entity2ID])
VALUES
(
INSERT INTO [#tblEntity1] ([Value])
OUTPUT [inserted].[ID] AS [entity1ID], #entity2ID AS [entity2ID]
VALUES ('One')
)
So the inner INSERT-OUTPUT statement will add a new entity to table #tblEntity1. The new entity's ID (which is set as IDENTITY(1, 1) will then be returned through the OUTPUT statement, along with a static value (which I already have in my code), to provide the two values for the outer INSERT statement.
The reason I think it might be possible is because execution of the inner INSERT-OUTPUT statement on its own returns a table anyway, and such output can usually be used to provide values for INSERT statements.
Obviously this example doesn't work; I was hoping it's just a simple syntax problem.
Thank you in advance for any comments and advice.
Your requirement is possible according to the documentation.
Assuming #tblIntersect has two matching id columns this should work
INSERT INTO [#tblEntity1] ([Value])
OUTPUT [inserted].[ID] AS [entity1ID], #entity2ID AS [entity2ID]
INTO #tblIntersect
VALUES ('One')

Is there a way i can do multiple inserts into one table using a condition?

Is there a way i can do multiple inserts into one table using a condition?
i have a list of subscribers in tbl_subscribers. i have an update on productX so i would like everyone who is subscribes to productX to get a notification. The user_notification table is id PK, user_id, notification_id. The two values i need is product_id (productX) which allows me to find a list of subscribers in tbl_subscribers and the notification_id to insert into the user_notification table.
How can i do this insert using one query? I see you can do a select statement in sqlite http://www.sqlite.org/lang_insert.html but i cannot wrap my head around how i may do this nor seen an example.
I believe you're looking from INSERT SELECT as outlined here:
http://www.1keydata.com/sql/sqlinsert.html
The second type of INSERT INTO allows
us to insert multiple rows into a
table. Unlike the previous example,
where we insert a single row by
specifying its values for all columns,
we now use a SELECT statement to
specify the data that we want to
insert into the table. If you are
thinking whether this means that you
are using information from another
table, you are correct. The syntax is
as follows:
INSERT INTO "table1" ("column1", "column2", ...)
SELECT "column3", "column4", ... FROM "table2"
insert into user_notification(user_id, notification_id)
select s.user_id, #notification_id
from tbl_subscriber s
where s.product_id = #productX