2013-02-11 19 views
0

我有一个名为sales_staff_08的表和姓,用户名为3列。如何更新过程中重复PL/SQL的记录

用户名使用名字和姓氏连接在一起。

因为它可能被复制。所以我想避免增加一些数字。

当前表

USERNAME 
---------- 
JOHSMITH1 
TOMNGUYE1 
STEREDMO1 
BOBJOHN1 
CARJONES1 
DANCREIG1 
STEREDMO1 
TOMNGUYE1 

我要来更新复制的记录,应该这个样子:

USERNAME 
---------- 
JOHSMITH1 
TOMNGUYE1 
STEREDMO1 
BOBJOHN1 
CARJONES1 
DANCREIG1 
STEREDMO2 
TOMNGUYE2 

我第一次尝试更新记录

CREATE OR REPLACE PROCEDURE proc_concate_names IS 

vc_username VARCHAR(25); 
v_number NUMBER (2) := 1; 

CURSOR cur_concate_username IS 
SELECT firstname, surname, username FROM sales_staff_08; 

BEGIN 

    FOR rec_cur_concate IN cur_concate_username 

    LOOP 

    vc_username := rec_cur_concate.firstname || rec_cur_concate.surname || v_number; 

    UPDATE sales_staff_08 ss 
    SET username = vc_username 
    WHERE ss.username = rec_cur_concate.username; 

END LOOP; 

END proc_concate_names; 
/
+0

我认为你必须改变你的表结构,主要是为每个名称添加唯一的ID,以便使用各自的id而不是rec_cur_concate.username来更新用户名。 或者我认为有一种使用触发器的可能方法。 – ajmalmhd04 2013-02-11 04:47:20

+0

其实我有sales_staff_id作为主键。 – 2013-02-11 14:14:18

回答

2

你可以用一条命令来完成:

merge into sales_staff_08 d 
using (select firstname ||surname || row_number() 
      over (partition by username order by firstname) un, rowid 
     from sales_staff_08) s 
on (d.rowid = s.rowid) 
when matched then update set d.username = s.un; 

Here is a sqlfiddle demo

由于@Plouf表示这也可以作为更新命令来完成:

update sales_staff_08 d 
set d.username = (
    select un from (
    select firstname ||surname || row_number() 
      over (partition by firstname, surname order by firstname) un 
    from sales_staff_08 
) s 
    where s.rowid = d.rowid 
) 

Here is another sqlfiddle

+0

为什么合并而不是简单的更新? – Plouf 2013-02-11 09:26:09

+1

@Plouf,这是因为我不知道如何在**简单**更新中做到这一点,只是一个非常简单**更新,恕我直言,合并是更好,因为查询保持干净。无论如何,因为你挑战,我会更新我的回答 – 2013-02-11 09:41:23

+0

我真的没有看到合并和更新之间的很多区别... – Plouf 2013-02-11 09:58:24

2

A.B.Cade答案是更可靠。首先,如果有数百万行,合并和更新将会更快。因为在第一种情况下,您正在使用plsql引擎和sql引擎进行操作。这意味着在每个plsql引擎的循环中,它都会调用sql引擎。在第二种情况下,它将使用更快的完全独立的sql引擎。

相关问题