Home » SQL & PL/SQL » SQL & PL/SQL » update sql script (11g2)
update sql script [message #603472] |
Mon, 16 December 2013 18:29 |
|
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 #603508 is a reply to message #603472] |
Tue, 17 December 2013 02:34 |
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 |
|
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 #603584 is a reply to message #603582] |
Tue, 17 December 2013 10:59 |
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 #603599 is a reply to message #603595] |
Tue, 17 December 2013 12:52 |
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 |
flyboy
Messages: 1903 Registered: November 2006
|
Senior Member |
|
|
anncao wrote on Tue, 17 December 2013 18:53OK, 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).
|
|
|
Goto Forum:
Current Time: Fri Apr 26 05:56:34 CDT 2024
|