Home » SQL & PL/SQL » SQL & PL/SQL » update sql script (11g2)
update sql script [message #603472] Mon, 16 December 2013 18:29 Go to next message
anncao
Messages: 87
Registered: August 2013
Member
I am new to oracle, would like to write a script (.sql file)that update a column in one table with a column data in another table.
The script will be run using SQL plus.

I have two questions:
I wrote the following query,


Begin
Merge INTO Storedgrades Sg USING
(SELECT Co.Credittype FROM Course Co
) ON ((Sg.Course_Number=Co.Course_Number) AND (NVL(Sg.Credit_Type,-1) <>Co.Credittype) )
WHEN Matched THEN
  Update Set Sg.Credit_Type=Co.Credittype
  --where (NVL(Sg.Credit_Type,-1) <>Co.Credittype);
End

For above merge statement, because I would like to only update credit type that is null or different, I am not sure where should I add the NVL(Sg.Credit_Type,-1) <>Co.Credittype, in the on condition part or in the where statement that I commented out.


Second question:

If we use SQLplus to run the script, what do I need to add in the script for example things like settings, or do I need to add a commit, or / etc at the end of the file?

Any update script example used by sqlplus that I can take a look online?

Thanks

[Updated on: Mon, 16 December 2013 18:37]

Report message to a moderator

Re: update sql script [message #603473 is a reply to message #603472] Mon, 16 December 2013 18:46 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
I suggest that you start this effort by composing a single SELECT statement that results in all the rows which should be UPDATED.

It would be helpful if you provided DDL (CREATE TABLE ...) for tables involved.
It would be helpful if you provided DML (INSERT INTO ...) for test data.
It would be helpful if you followed Posting Guidelines - http://www.orafaq.com/forum/t/88153/0/311
It would be helpful if you provided expected/desired results & a detailed explanation how & why the test data gets transformed or organized.
Re: update sql script [message #603474 is a reply to message #603473] Mon, 16 December 2013 18:54 Go to previous messageGo to next message
anncao
Messages: 87
Registered: August 2013
Member
Thanks, sorry, I am not sure I understand when you say SELECT statement that results in all the rows which should be UPDATED.
So is my script correct? or should I use where clause to filter out the records as I commented out
attached are table scripts.
Re: update sql script [message #603475 is a reply to message #603474] Mon, 16 December 2013 19:46 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
which rows need to be UPDATED?

how do you identify which rows get changed?
Re: update sql script [message #603508 is a reply to message #603472] Tue, 17 December 2013 02:34 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
The MERGE statement you posted should fail as CO.COURSE_NUMBER used in ON clause is not present in USING clause and CO alias is misplaced.

Even if it would be corrected, you have a logical problem: what shall be the result, when there are multiple CREDITTYPE values in CO table and multiple rows in SG table with the same SG.COURSE_NUMBER?

I recommend you to take your current data (or create a set of representative ones) and try to figure out yourself, what shall be the result for the case above.
Re: update sql script [message #603523 is a reply to message #603472] Tue, 17 December 2013 03:44 Go to previous messageGo to next message
mokarem
Messages: 109
Registered: November 2013
Location: Dhaka
Senior Member

Begin

Merge INTO Storedgrades Sg
USING Course Co
ON ((Sg.Course_Number=Co.Course_Number) AND (NVL(Sg.Credit_Type,-1) <>Co.Credittype))
WHEN Matched THEN
Update Set Sg.Credit_Type=Co.Credittype;

commit;

End;
/
Re: update sql script [message #603582 is a reply to message #603523] Tue, 17 December 2013 10:55 Go to previous messageGo to next message
anncao
Messages: 87
Registered: August 2013
Member
Thanks all. The result is I would like to update credittype column in storedgrades table the same as credittype in the course table according to course_number column in both tables. the two tables relation can be joined using course_number.

I think mokarem's query looks great, that helped me to understand Oracle merge statement. It looks like I don't need to even use select subquery.

But I am curious is this below going to be the same as mokarem's query? thanks

Begin

Merge INTO Storedgrades Sg
USING (SELECT course_number, Credittype from Course) Co
ON ((Sg.Course_Number=Co.Course_Number) AND (NVL(Sg.Credit_Type,-1) <>Co.Credittype))
WHEN Matched THEN
Update Set Sg.Credit_Type=Co.Credittype;

commit;

End;
/
Re: update sql script [message #603584 is a reply to message #603582] Tue, 17 December 2013 10:59 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Do you really require the begin end block to transform a simple merge sql into an anonymous pl/sql block?
Where are you making the execution call to this block? To be more clear, I mean is this a call from an application frontend or is it being simply executed in the backend?

[Updated on: Tue, 17 December 2013 11:00]

Report message to a moderator

Re: update sql script [message #603585 is a reply to message #603584] Tue, 17 December 2013 11:03 Go to previous messageGo to next message
anncao
Messages: 87
Registered: August 2013
Member
Since this will be scheduled to be an automatic update script running each night, I would like to put this script in a .sql file and use sqlplus command line to run this sql file.
so does this work?

Thanks

[Updated on: Tue, 17 December 2013 11:04]

Report message to a moderator

Re: update sql script [message #603588 is a reply to message #603585] Tue, 17 December 2013 11:22 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>Since this will be scheduled to be an automatic update script running each night
Why not fix the root cause so the data does not have to be adjusted nightly?
Re: update sql script [message #603589 is a reply to message #603588] Tue, 17 December 2013 11:26 Go to previous messageGo to next message
anncao
Messages: 87
Registered: August 2013
Member
The root course will be fixed by interface developer in the near future. But until then , we have to run this backend fix.
Re: update sql script [message #603590 is a reply to message #603589] Tue, 17 December 2013 11:31 Go to previous messageGo to next message
anncao
Messages: 87
Registered: August 2013
Member
Thanks, I have not tried in SQL plus to run the script yet. I thought for each script I should put them into begin and end block. So it sounds I am wrong.
also the above merge statement, is it equivalent to the following? I worked in SQL server environment, the update with joins make update quite simple, but oracle doesnot allow using join in the statement. SO tried to learn what is the best way to write update queries (update data from another table).

UPDATE Storedgrades Sg
SET Sg.Credit_Type=
(SELECT credit_type
FROM
FROM Course CO
WHERE Sg.Course_Number=Co.Course_Number
)
Where (Nvl(Sg.Credit_Type,-1) <>Co.Credittype))
AND EXISTS
(SELECT Course_Number Co FROM Course WHERE sg.course_number=co.course_number
);
Thanks
Re: update sql script [message #603593 is a reply to message #603590] Tue, 17 December 2013 11:48 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
anncao wrote on Tue, 17 December 2013 09:31
Thanks, I have not tried in SQL plus to run the script yet. I thought for each script I should put them into begin and end block. So it sounds I am wrong.
also the above merge statement, is it equivalent to the following? I worked in SQL server environment, the update with joins make update quite simple, but oracle doesnot allow using join in the statement. SO tried to learn what is the best way to write update queries (update data from another table).

UPDATE Storedgrades Sg
SET Sg.Credit_Type=
(SELECT credit_type
FROM
FROM Course CO
WHERE Sg.Course_Number=Co.Course_Number
)
Where (Nvl(Sg.Credit_Type,-1) <>Co.Credittype))
AND EXISTS
(SELECT Course_Number Co FROM Course WHERE sg.course_number=co.course_number
);
Thanks


> FROM
> FROM Course CO

FROM FROM ??????
do not post invalid syntax here.
Re: update sql script [message #603594 is a reply to message #603590] Tue, 17 December 2013 11:51 Go to previous messageGo to next message
anncao
Messages: 87
Registered: August 2013
Member
That's the hard part, I searched online to see examples of oracle updates posted by different people, I was still not very clear, that is why I come to this forum. And I also looked in oracle site, looked documentations like PL SQL, not very luck. I would like to find a good oracle documentation about updates statement. Could you recommend a link to the best SQL documentation for oracle SQL esp,that talks this update involved in multiple tables.

Thanks
Re: update sql script [message #603595 is a reply to message #603594] Tue, 17 December 2013 11:53 Go to previous messageGo to next message
anncao
Messages: 87
Registered: August 2013
Member
UPDATE Storedgrades Sg
SET Sg.Credit_Type=
(SELECT credit_type
FROM Course CO
WHERE Sg.Course_Number=Co.Course_Number
)
Where (Nvl(Sg.Credit_Type,-1) <>Co.Credittype))
AND EXISTS
(SELECT Course_Number Co FROM Course WHERE sg.course_number=co.course_number
);

OK, corrected, could you answer the question please?
Re: update sql script [message #603596 is a reply to message #603595] Tue, 17 December 2013 12:01 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>OK, corrected,
REALLY?
I don't think so.

>Where (Nvl(Sg.Credit_Type,-1) <>Co.Credittype))
unmatched parenthesis above
Re: update sql script [message #603599 is a reply to message #603595] Tue, 17 December 2013 12:52 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
anncao wrote on Tue, 17 December 2013 23:23

OK, corrected, could you answer the question please?


If you are not comfortable using SQL*Plus or any tool to check the format and syntax. You could try to format your code at SQL Formatter. If any syntax error it won't respond.
Re: update sql script [message #603659 is a reply to message #603595] Wed, 18 December 2013 04:25 Go to previous message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
anncao wrote on Tue, 17 December 2013 18:53
OK, corrected, could you answer the question please?

You are joking, right? Anyway,

as it seems you are incapable to create a simple testcase demonstrating your problem. Note, that those tables do not have all columns as your, as the other ones are not important. I also suffixed table names with _TEST not to mess the real tables (if you tried to run it). Also have a look at a few INSERT statements for creation of some representative data (note that the number of rows for both COURSE_NUMBERs differs).
create table courses_test
(	dcid number(10,0) constraint courses_pk primary key, 
	id number(10,0), 
	course_number varchar2(11 char), 
	code varchar2(20 char), 
	credittype varchar2(20 char) 
);

create table storedgrades_test 
(	dcid number(10,0) constraint storedgrades_pk primary key, 
	studentid number(10,0), 
	termid number(10,0), 
	storecode varchar2(10 char),
	course_number varchar2(11 char),
	credit_type varchar2(20 char) 
);

insert into courses_test( dcid, id, course_number, code, credittype ) values( 1, 1, 'AAA', 'Test 1', 1 );
insert into courses_test( dcid, id, course_number, code, credittype ) values( 2, 1, 'BBB', 'Test 1', 1 );
insert into courses_test( dcid, id, course_number, code, credittype ) values( 3, 1, 'BBB', 'Test 3', 3 );
insert into courses_test( dcid, id, course_number, code, credittype ) values( 4, 1, 'BBB', 'Test 5', 5 );

insert into storedgrades_test( dcid, studentid, termid, storecode, course_number, credit_type ) values( 1, 1, 1, 'Test 1', 'AAA', 1 );
insert into storedgrades_test( dcid, studentid, termid, storecode, course_number, credit_type ) values( 2, 1, 1, 'Test 2', 'AAA', 2 );
insert into storedgrades_test( dcid, studentid, termid, storecode, course_number, credit_type ) values( 3, 1, 1, 'Test 1', 'BBB', 1 );
insert into storedgrades_test( dcid, studentid, termid, storecode, course_number, credit_type ) values( 4, 1, 1, 'Test 4', 'BBB', 4 );

commit;

select * from courses_test;

      DCID         ID COURSE_NUMB CODE                 CREDITTYPE
---------- ---------- ----------- -------------------- --------------------
         1          1 AAA         Test 1               1
         2          1 BBB         Test 1               1
         3          1 BBB         Test 3               3
         4          1 BBB         Test 5               5

select * from storedgrades_test;

      DCID  STUDENTID     TERMID STORECODE  COURSE_NUMB CREDIT_TYPE
---------- ---------- ---------- ---------- ----------- --------------------
         1          1          1 Test 1     AAA         1
         2          1          1 Test 2     AAA         2
         3          1          1 Test 1     BBB         1
         4          1          1 Test 4     BBB         4

MERGE INTO storedgrades_test sg
USING courses_test co
ON ((sg.course_number=co.course_number)
    AND (nvl(sg.credit_type,-1) <>co.credittype))
WHEN MATCHED THEN UPDATE SET sg.credit_type=co.credittype;

ERROR at line 3:
ORA-38104: Columns referenced in the ON Clause cannot be updated:
"SG"."CREDIT_TYPE"

UPDATE storedgrades_test sg
SET sg.credit_type=
  ( SELECT co.credittype
    FROM courses_test co
    WHERE sg.course_number=co.course_number
      AND nvl(sg.credit_type,-1) <>co.credittype )
WHERE EXISTS
  ( SELECT co.course_number
    FROM courses_test co
    WHERE sg.course_number=co.course_number
      AND nvl(sg.credit_type,-1) <>co.credittype );

ERROR at line 3:
ORA-01427: single-row subquery returns more than one row

The actually corrected UPDATE statement will fail due to the logic. Because, for SG.COURSE_NUMBER='BBB' there are in CO table
- two non-matching rows for SG.CREDIT_TYPE=1 (those with CO.CREDITTYPE=3 and 5)
- three non-matching rows for SG.CREDIT_TYPE=4 (all).
Also, for SG.COURSE_NUMBER='AAA', is it correct to UPDATE the row with SG.CREDIT_TYPE=2 to 1 (as you described logic dictates it)?

And, I did not consider duplicates in (COURSE_NUMBER, CREDIT_TYPE) - that would bring another possible variants to your case.

So, tell me, for this data, what shall be the result? Or any data you have which are not breaking table constraints (there were none in the script you posted except of primary keys on DCID columns). And, of course, why? Describe the steps leading to it. The most comprehensive you are able to. Then, it will be easy to implement them using SQL statement.

P.S. If SQL server will not fail with this approach, just do not be surprised when you have data messed data after the UPDATE statement (more then before calling it).
Previous Topic: LAG & LEAD Question
Next Topic: insert into
Goto Forum:
  


Current Time: Fri Apr 26 05:56:34 CDT 2024