PL / SQL Oracle - 根据名称作为键,从表1中的表2插入ID,如果找不到名称

时间:2017-07-19 18:03:56

标签: sql oracle merge

PL / SQL - 根据Name作为键,从表1中的表2插入ID,如果在Oracle中找不到Name,则可以重复并更新表2。

我必须创建一个执行上述任务的存储过程

鉴于表1:TEST1

Name |  Data  | ID |
Tim  |  Test1 |    |
Jim  |  Test2 |    |
Jim  |  Test3 |    |
Roy  |  Test4 |    |
Matt |  Test5 |    |

鉴于表2:TEST2(ID自动生成)

ID   |  Name  |
23   |  Tim   | 
24   |  Jim   | 
20   |  Matt  |

需要结果表:

Name |  Data  | ID |
Tim  |  Test1 | 23 |
Jim  |  Test2 | 24 |
Jim  |  Test3 | 24 |
Roy  |  Test4 | x  |
Matt |  Test5 | y  |

其中x,y是Roy和Matt新生成的ID,如果在TEST2中找不到名称

我写了以下代码:

MERGE INTO TEST1 b
USING (
  SELECT ID, NAME FROM TEST2) e
ON (b.NAME = e.NAME)
WHEN MATCHED THEN
  UPDATE SET b.CODE = E.ID
WHEN NOT MATCHED THEN
  INSERT (b.CODE)
  VALUES ('NONE');

产生

Name |  Data  | ID |
Tim  |  Test1 | 23 |
Jim  |  Test2 | 24 |
Jim  |  Test3 | 24 |
Roy  |  Test4 | -  |
Matt |  Test5 | -  |

我没有得到在TEST2中同时插入新行并获取数据的逻辑。

请帮助!!

2 个答案:

答案 0 :(得分:1)

请尝试(ad-hoc PL / SQL,但您可以在测试后更改为程序)

const App = () => {
  return (
    <Router>
      <div>
        <Link to='/scoreBoard'>ScoreBoard</Link>
        <Switch>
          <Route exact path='/' render={() => <h1>Home</h1>}/>
          <Route path='/scoreBoard' component={ScoreBoard}/>
          <Route path='/scoreBoard/add' component={AddScorePanel}/>
        </Switch>
      </div>
    </Router>
  );
};

const ScoreBoard = ({match}) => {
  return (
    <div>
      <h1>ScoreBoard</h1>
      <Link to={`${match.url}/add`}>Add</Link>
    </div>
  );
};

const AddScorePanel = ({match}) => {
  return (
    <div>
      <h1>Add</h1>
      <Link to={`${match.url}/..`}>Back</Link>
    </div>
  );
};

test_sequence是

DECLARE
  TYPE test_cur_type IS REF CURSOR RETURN test1%ROWTYPE;
  test_cur test_cur_type;
  test_row test1%rowtype;
BEGIN
  OPEN test_cur FOR SELECT name, data, id FROM test1;
  LOOP
    FETCH test_cur INTO test_row;
    EXIT WHEN test_cur%NOTFOUND;
    INSERT INTO test3 (name, data, id)
    VALUES (test_row.name, test_row.data,
      NVL(SELECT id FROM test2 
           WHERE name=test_row.name AND ROWNUM <= 1, test_sequence.nextval));
  END LOOP;
 CLOSE test_cur;
END;

并且test2和test3两个表都具有 CREATE SEQUENCE test_sequence INCREMENT BY 1 MAXVALUE 5000 CACHE 20;

的以下定义
id

此脚本允许您在每个行级别上实现任何复杂逻辑,并且可以通过批量更新进一步优化(如果需要(避免过早优化)(避免pl / sql - sql上下文切换开销)

答案 1 :(得分:0)

我提出了一个问题,可能很天真,但现在已经完成了我的任务。以下是代码

create or replace procedure TestProc as
begin
MERGE INTO TEST2 T2
   USING (SELECT DISTINCT NAME FROM TEST1) T1
         ON (T1.NAME = T2.NAME)
   WHEN NOT MATCHED THEN
       INSERT (T2.NAME) VALUES (T1.NAME);
MERGE INTO TEST1 b
USING (
  SELECT ID, NAME
  FROM TEST2) e
ON (b.NAME = e.NAME)
WHEN MATCHED THEN
  UPDATE SET b.CODE = E.ID
WHEN NOT MATCHED THEN
  INSERT (b.CODE)
  VALUES ('NONE');
 end;

欢迎进一步的优化和想法。谢谢!