2013-02-11 40 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引擎。

相關問題