2

我有一张桌子

CREATE TABLE STUDENT
(
  ID            INTEGER PRIMARY KEY,
  FIRSTNAME     VARCHAR2(1024 CHAR),
  LASTNAME      VARCHAR2(1024 CHAR),
  MODIFIEDDATE  DATE  DEFAULT sysdate
)

我正在插入一行数据

insert into STUDENT (ID, FIRSTNAME, LASTNAME, MODIFIEDDATE)  values (1,'Scott', 'Tiger', sysdate);

当我必须插入一条数据记录时,我需要编写一个执行以下操作的过程或函数:

  1. 如果没有相同 id 的记录,则插入该行。
  2. 如果有相同 id 和数据匹配的记录,则什么也不做。
  3. 如果有相同 id 的记录但数据不匹配,则更新数据。

我是甲骨文的新手。从 java 端,可以通过 id 选择记录,然后更新该记录,但这会进行 2 次数据库调用。只是为了避免我尝试使用过程更新表。如果可以在单个数据库调用中完成相同的操作,请提及。

4

3 回答 3

3

对于单个 SQL 语句解决方案,您可以尝试使用MERGE语句,如本答案所述https://stackoverflow.com/a/237328/176569

例如

create or replace procedure insert_or_update_student(
p_id number, p_firstname varchar2, p_lastname varchar2
) as
begin
    merge into student st using dual on (id = p_id)
         when not matched then insert (id, firstname, lastname) 
           values (p_id, p_firstname, p_lastname)
         when matched then update set 
           firstname = p_firstname, lastname = p_lastname, modifiedate = SYSDATE
end insert_or_update_student;
于 2012-10-03T09:46:20.257 回答
3

而不是过程尝试在 oracle 中使用合并。如果值匹配,它将更新表,如果未找到值,它将插入值

MERGE INTO bonuses b
USING (
  SELECT employee_id, salary, dept_no
  FROM employee
  WHERE dept_no =20) e
ON (b.employee_id = e.employee_id)
WHEN MATCHED THEN
  UPDATE SET b.bonus = e.salary * 0.1
  DELETE WHERE (e.salary < 40000)
WHEN NOT MATCHED THEN
  INSERT (b.employee_id, b.bonus)
  VALUES (e.employee_id, e.salary * 0.05)
  WHERE (e.salary > 40000)

试试这个

于 2012-10-03T09:47:46.227 回答
0

要解决第二个任务 - “如果有相同 id 和数据匹配的记录,则什么也不做。” - 从 10g 开始,我们在合并运算符的更新和插入部分中添加了额外的“where”子句。要完成这项任务,我们可以添加一些数据更改检查:

    when matched then update
        set student.last_name = query.last_name 
           where student.last_name <> query.last_name

这将仅更新匹配的行,并且仅更新数据已更改的行

于 2017-06-08T09:25:44.857 回答