SQL On Delete Trigger - sql

I am trying to create a trigger that when a row is deleted from a table it gets inserted in another table:
1 Create Or Replace Trigger cancel
2 After Delete
3 On OrderTable
4 For EACH ROW
5 Begin
6 Insert Into CancelledOrders Values (:old.acctNum, age, phone)
7 From OrderTable Natural Join Customer
8 Where acctid = :old.acctNum AND menuid = :old.menuNum;
9 End;
10 /
11 Show Errors;
I want to grab the acctNum, age, and phone. The acctNum is from the Order table but the age and phone is from the Customer table. Therefore I join the two tables (on the acctid key). So the joined result will look like this:
acctNum Age Phone
I get this error when I try to compile the Trigger:
2/2 PL/SQL: SQL Statement ignored
3/2 PL/SQL: ORA-00933: SQL command not properly ended
Does anyone know the problem?
EDIT:
Table Structure:
OrderTable: AcctNum MenuNum startOrder endOrder
Customer Table: AcctNum age phone

You're mixing the values and select (subquery) syntax, which are for different things. You can insert from a query that uses a value from the :old pseudorecord and values from the customer table:
Insert Into CancelledOrders -- (acctNum, age, phone)
Select :old.acctNum, age, phone
From Customer
Where acctNum = :old.acctNum;
It's better to specify the columns in the target table as part of the insert clause (I've left that commented out in case the names are different). You also don't want (or need) to requery the table the trigger is against; you already have the data you need, and it will get a mutating-table error in some circumstances. So no join is needed.

Your insert statement is incorrect. You need to specify the columns you want to select in the tables.
Add the select clause to your insert statement. Also, removed the values keyword and specify column names:
Insert Into CancelledOrders (acctNum, age, phone)
Select :old.acctNum, age, phone
From OrderTable Natural Join Customer
Where acctid = :old.acctNum AND menuid = :old.menuNum;

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.

Create table with other table data

Following query works but i want with 2 fields
CREATE TABLE TOTAPPS (ANUM) AS SELECT a.A# FROM APPLICANT a.
This is work that
//TOTAPPS
ANUM
--------
if i want to create with 2 fields?
//Totapps
ANUM NUMBER
---------------------------
how should i create the table? in order to get the correct out?
and the NUMBER is refer to the ANUM , for example
CREATE TABLE TOTAPPS (ANUM) AS SELECT a.A# FROM APPLICANT a,
(NUMBER) AS SELECT COUNT(*) FROM a.A#;
but it's failed to work.
Calling a column NUMBER is not correct as it is a reserved word. Assuming from your second query that you want to add to your table distinct values of a.A# and the count of these values in the table, you should try this:
CREATE TABLE TOTAPPS (ANUM, MYNUMBER) AS
SELECT a.A#, COUNT(a.A#) FROM APPLICANT a GROUP BY a.A#;

merge statement when not matched by source then insert to another table

I have created two tables customersrc and customertemp with the columns:
customertemp
ID name age addr cityid isactive
34 Gi 24 Chennai 1 1
customersrc
CustomerId CustomerName CustomerAge CustomerAddress
1 Gi 24 madurai
2 Pa 23 Tirupur
3 MI 27 Tirupur
Now I need to insert pa and mi data value to the temp table bcz it is not matched with the rows of customertemp. And the row gi data will be updated which was matched.
I used the following MERGE statement
DECLARE #cityid INT SET #cityid=1
MERGE Temp.dbo.customersrc as src_customer
USING ( SELECT CustomerName,CustomerAge,CustomerAddress FROM customertemp) as temp_customer
ON src_customer.name=temp_customer.CustomerName
AND
src_customer.cityid=#cityid
WHEN MATCHED THEN
UPDATE SET
src_customer.age=temp_customer.CustomerAge,
src_customer.addr=temp_customer.CustomerAddress,
src_customer.isactive=1
WHEN NOT MATCHED BY SOURCE THEN
UPDATE SET src_customer.isactive=0 ; -- here i need the insert statement to insert in another table
Questions:
is it possible to write insert statement inside the when not matched by source query?
if it is not possible then how to achieve this using merge?
in a simple set theory I need to put the customersrc(table_B)-customertemp (table_A). B-A value into the another or temp table.
One of the main usages of the MERGE statement is to perform so called "UPSERTS" (Update matching records, insert new records), so it is definitely possible to do what you want. Just add the following to the last part of your MERGE statement:
WHEN NOT MATCHED BY TARGET THEN
INSERT (name, age, addr, cityid, isactive)
VALUES (CustomerName, CustomerAge, CustomerAddress, #cityid, 1)
If you also need to insert data into a 3rd table, depending on whether rows are updated or inserted, you can use the OUTPUT clause of the merge statement. Check out the documentation: http://technet.microsoft.com/en-us/library/ms177564.aspx
Me: Why do you want to insert to another table?
You: To show the user who are not in the customertemp table.
So your requirement is not to insert into another table. Your requirement is to get the missing users.
You could do that with a dummy UPDATE (SET SomeCol = SomeCol) and OUTPUT. But that is a hack that I would try to avoid.
It is probably easier to do this in two statements. Here's how you'd get the missing rows:
SELECT temp_customer.*
FROM (SELECT CustomerName,CustomerAge,CustomerAddress FROM customertemp) as temp_customer
LEFT JOIN customersrc ON src_customer.name=temp_customer.CustomerName AND src_customer.cityid=#cityid
WHERE customersrc.cityid IS NULL

oracle unique constraint

I'm trying to insert distinct values from one table into another. My target table has a primary key studentid and when I perform distinct id from source to target the load is successful. When I'm trying to load a bunch of columns from source to target including student_id, I'm getting an error unique constraint violated. There is only one constraint on target which is the primary key on studentid.
my query looks like this (just an example)
insert into target(studentid, age, schoolyear)
select distinct id, age, 2012 from source
Why does the above query returns an error where as the below query works perfectly fine
insert into target(studentid)
select distinct id from source
help me troubleshoot this.
Thanks for your time.
In your first query you are selecting for distinct combination of three columns ie,
select distinct id, age, 2012 from source
Not the distinct id alone. In such case there are possibility for duplicate id's.
For example, Your above query is valid for this
id age
1 23
1 24
1 25
2 23
3 23
But in your second query you are selecting only distinct id's
select distinct id from source
So this will return like,
id
1
2
3
In this case there is no way for duplicates and your insert into target will not
fail.
If you really want to do bulk insert with constrain on target then go for
any aggregate functions
select id, max(age), max(2012) group by id from source
Or if you dont want to loose any records from source to target then remove your constraint on target and insert it.
Hope this helps

Data to be inserted by SSIS

I have a table known as Customer(DATABASE AAA) containing 3 fields
Cust_id Cust_name Cust_salary
1 A 2000
2 B 3000
3 C NULL
I want to put data of these 3 columns in Employee(DATABASE BBB) which has the same structure as of Customer.
I want to transfer records of only those customer in which Cust_salary part is not null.
This work is to be done in SSIS only. MY values for Cust_id is auto generated & before putting values to Employee_id,the Employee table should be deleted.The auto generated identity should be preserved.
You could create a SQL Execute Task in SSIS and run the following:
INSERT INTO Employee
(EmployeeId, EmployeeName, EmployeeSalary)
SELECT Cust_id, Cust_name, Cust_salary
FROM Customer
WHERE Cust_salary IS NOT NULL
Darren Davies answer seems correct, but if for some obscure reason you have an EmployeeID is also an identity column and needs to match Cust_ID, and assuming any entries already in the Employee table correspond with the correct customer you can use an Execute SQL Task in SSIS with a connection open to Database BBB to run the following:
SET IDENTITY_INSERT Employee ON
INSERT INTO Employee (EmployeeID, EmployeeName, EmployeeSalary)
SELECT Cust_ID, Cust_Name, Cust_Salary
FROM AAA..Customer
WHERE Cust_Salary IS NOT NULL
AND NOT EXISTS
( SELECT 1
FROM Employee
WHERE EmployeeID = Cust_ID
)
SET IDENTITY_INSERT Employee OFF
This will maintain the integrity of the Identity fields in each table, and only insert new Customers to the Employee table.
what have you tried?
You will need two connections, one for each DB and one data flow component which will have a OleDBSource and an OleDBDestination component inside.
On the OleDBSource you can select your connection and write your query and then you drag the green arrow to the OleDBDestination. Double click the OleDBDestination select destination connection and table and click on mapping.
Should be it