Oracle Code to insert data into table that doesn't exist - sql

I am trying to insert data into a table in Oracle database. Data already exists, but not all of the data, and I can't just delete the data and reinsert it all. Is there a way to insert data into the table (without knowing what data I am missing). My script is running, but no data is actually inserting (and I do know there is data missing. I intentionally took data out to test its re-insertion.)
Insert into item (item, descr)
select distinct a.SUBORD, a.SUBORD_DESCR FROM EXIDE.UDT_BOM a, item b
where b.item = a.subord and not exists
(select b.item from item b, exide.udt_bom a where a.subord = b.ITEM)

If I follow what you're doing, you can use the merge statement for this:
merge into item i
using (select subord, subord_descr from exide.udt_bom) u
on (i.item = u.subord)
when not matched then insert (item, descr) values (u.subord, u.subord_descr);
SQL fiddle demo.
This also has the advantage that if the udt_bom has new descriptions for existing items, you can update those in the item table too:
merge into item i
using (select subord, subord_descr from exide.udt_bom) u
on (i.item = u.subord)
when matched then update set descr = u.subord_descr
when not matched then insert (item, descr) values (u.subord, u.subord_descr);
Another fiddle.

You have too many references to too many tables. With the not exists clause, the query does not need explicit joins:
Insert into item(item, descr)
select distinct b.SUBORD, b.SUBORD_DESCR
FROM EXIDE.UDT_BOM b
where not exists (select i.item from item i where b.subord = i.ITEM);
If there are no duplicates, in udt_bom, I would get rid of the distinct as well. And, queries are more readable when you use table abbreviations as aliases, rather than meaningless letters like a, b, and so on.

Related

How to return ids of rows with conflicting values?

I am looking to insert or update values in an SQLite database (version > 3.35) avoiding multiple queries. upsert along with returning seems promising :
CREATE TABLE phonebook2(
name TEXT PRIMARY KEY,
phonenumber TEXT,
validDate DATE
);
INSERT INTO phonebook2(name,phonenumber,validDate)
VALUES('Alice','704-555-1212','2018-05-08')
ON CONFLICT(name) DO UPDATE SET
phonenumber=excluded.phonenumber,
validDate=excluded.validDate
WHERE excluded.validDate>phonebook2.validDate RETURNING name;
This helps me track names corresponding to inserted/modified rows. How to find rows where phonebook2 values conflict with values upserted in above statement, but no insert or update happened due to where clause?
The RETURNING clause can't be used to get non-affected rows.
What you can do is execute a SELECT statement before the UPSERT:
WITH cte(name, phonenumber, validDate) AS (VALUES
('Alice', '704-555-1212', '2018-05-08'),
('Bob','804-555-1212', '2018-05-09')
)
SELECT *
FROM phonebook2 p
WHERE EXISTS (
SELECT *
FROM cte c
WHERE c.name = p.name AND c.validDate <= p.validDate
);
In the CTE you may include as many tuples as you want

How to insert into a SQL table via snaplogic pipeline depending on the existence of a data

I am new to snaplogic. I have 2 tables(A, B) in SQL Server as below. I need to insert data from table A into table B based on the existence of numberID in B.
If numberID of A exists in B, I need to update the name in B.
If numberID of A doesn't exist in B, I have to insert the row in table B.
I would like to know how to perform case disjunction. I wanted to use a router or a conditional snap but I don't understand how to use them with the result of the SQL query. I need help please.
you can use merge function
MERGE INTO B AS Target
USING (select * from A)
AS Source
ON Target.id = Source.id
WHEN MATCHED THEN
UPDATE SET B.Name = Source.Name
WHEN NOT MATCHED BY TARGET THEN
INSERT (Name) VALUES (source.NewName)
https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver15

Updating a lot of Data in One Field using Where clause

I am trying to update one filled with a lot of data.
This is my table
I want to update NameAlias with new names for Major but this is my question if I have a lot of major names and ids how can I write a query that is good and short?
I know it should be something like this for one column.
Update Major Set NameAlias='Mathemathic' where IdMajor=1;
But what should I do if I have a lot of data for one field?
I want my result to be something like this:
You can use case when expression -
Update Major Set NameAlias=
case when namemajor='Math' then 'Mathemathic'
when namemajor='Computer' then 'Software'
when namemajor='Art' then 'Painthing'
when namemajor='History' then 'FranceHistory'
when namemajor='Music' then 'Piano' end
You should create a temp table containing the id, NameAlias accordingly like below.
select Id, NameAlias
into #TempTable
from (
values(1, 'Mathemathic'),
(2, 'Software'),
(3, 'Painthing')
-- The rest of values
)v(Id, NameAlias)
Then you can update the Major table
Update m
SET m.NameAlias = t.NameAlias
From Major m
INNER JOIN #TempTable t on m.IdMajor = t.Id
There is no need to create a temporary table to do this. Just use a derived table in the update query:
update m
set m.NameAlias = v.newAlias
from Major m join
(values(1, 'Mathematic'),
(2, 'Software'),
(3, 'Painting')
) v(idMajor, newAlias)
on m.IdMajor = v.IdMajor;

SQL Insert/Update Issue

I am trying to update one table from another, im able to update fine as long as the customer record exists, but there are some entries that dont.
To solve this i've tried running the following insert
SELECT *
INTO SalBudgetCust
FROM SalBudgetCust_temp
WHERE NOT EXISTS (
SELECT Customer
FROM SalBudgetCust
WHERE Customer = SalBudgetCust_temp.Customer
)
but im prompted with
There is already an object named 'SalBudgetCust' in the database.
Im stuck at this point... could anyone offer a little guideance?
SELECT INTO implicitly creates the table you name. You should instead use INSERT INTO ... SELECT * FROM ..., so that the existing table is used.
It should be INSERT INTO instead of SELECT * INTO ... like
INSERT INTO SalBudgetCust SELECT * FROM SalBudgetCust_temp
WHERE NOT EXISTS
(
SELECT Customer FROM SalBudgetCust WHERE Customer = SalBudgetCust_temp.Customer
)
The general syntax to insert data of one table into another is :
INSERT INTO new_table
SELECT * FROM old_table
WHERE some_condition;
Where, new_table is the table where you want to insert data, old_table is table from where you are fetching data and some_condition is the expression / condition based upon which you want to fetch data from old table.
You may use other clauses like order by, group by, and even sub queries after where clause.
May refer this SQL INSERT INTO and it's subsequent pages.

Deleting at most one record for each unique tuple combination

I want to delete at most one record for each unique (columnA, columnB)-tuple in my following delete statement:
DELETE FROM tableA
WHERE columnA IN
(
--some subqueryA
)
AND columnB IN
(
--some subqueryB
)
How is this accomplished? Please only consider those statements that work when used against MSS 2000 (i.e., T-SQL 2000 syntax). I can do it with iterating through a temptable but I want to write it using only sets.
Example:
subqueryA returns 1
subqueryB returns 2,3
If the original table contained
(columnA, columnB, columnC)
5,2,5
1,2,34
1,2,45
1,3,86
Then
1,2,34
1,3,86
should be deleted. Each unique (columnA, columnB)-tuple will appear at most twice in tableA and each time I run my SQL statement I want to delete at most one of these unique combinations - never two.
If there is one record for a given unique (columnA, columnB)-tuple,
delete it.
If there are two records for a given unique (columnA,
columnB)-tuple, delete only one of them.
Delete tabA
from TableA tabA
Where tabA.columnC in (
select max(tabAA.columnC) from TableA tabAA
where tabAA.columnA in (1)
and tabAA.columnB in (2,3)
group by tabAA.columnA,tabAA.columnB
)
How often are you going to be running this that it matters whether you use temp tables or not? Maybe you should consider adding constraints to the table so you only have to do this once...
That said, in all honesty, the best way to do this for SQL Server 2000 is probably to use the #temp table as you're already doing. If you were trying to delete all but one of each dupe, then you could do something like:
insert the distinct rows into a separate table
delete all the rows from the old table
move the distinct rows back into the original table
I've also done things like copy the distinct rows into a new table, drop the old table, and rename the new table.
But this doesn't sound like the goal. Can you show the code you're currently using with the #temp table? I'm trying to envision how you're identifying the rows to keep, and maybe seeing your existing code will trigger something.
EDIT - now with better understood requirements, I can propose the following query. Please test it on a copy of the table first!
DELETE a
FROM dbo.TableA AS a
INNER JOIN
(
SELECT columnA, columnB, columnC = MIN(columnC)
FROM dbo.TableA
WHERE columnA IN
(
-- some subqueryA
SELECT 1
)
AND columnB IN
(
-- some subqueryB
SELECT 2 UNION SELECT 3
)
GROUP BY columnA, columnB
) AS x
ON a.columnA = x.columnA
AND a.columnB = x.columnB
AND a.columnC = x.columnC;
Note that this doesn't confirm that there are exactly one or two rows that match the grouping on columnA and columnB. Also note that if you run this twice it will delete the remaining row that still matches the subquery!