2009-10-13 74 views
1

我是Oracle PL/SQL的新手,並且在記錄方面有一些難以概念化的集合。PLSQL集合 - 創建一個記錄集合還是不是?

我有以下問題: 我想比較客戶表中記錄的各個字段與人表中記錄的各個字段。例如,LName,FName,Soc。 (不幸的是,沒有標識符可以輕鬆鏈接兩者)。

對於客戶端表,我打算創建一個遊標並將其提取到一條記錄(和循環)中,因爲客戶端表的每條記錄都是,所以我想查看所有人員記錄並查看是否存在是最匹配的。如果有100個客戶,則不應有超過100個匹配。

這是我不知道我是否應該:

  • A)使用記錄的集合 人表,或
  • B)使用 集合LName的,集合 FName是Soc的集合。

如果我使用A,如何引用記錄中的特定列?這就是我正在執行的代碼,但我有點迷路。

如果我使用B,有沒有辦法確保我比較具有相同記錄的列?即如果我比較John Doe 111-222-3333的客戶記錄,我想確保如果我得到的匹配來自單個記錄,而不記錄10 FName = John,則記錄200 LNAME = Doe,記錄5000 Soc = 111-222-3333。

答案與Oracle PL/SQL語法是極大的讚賞,因爲我仍然在學習,會被其他語言太容易混淆......下面是我的代碼的開始......

謝謝!

DECLARE 
    CURSOR client_cur IS 
    SELECT id_client, nm_client_last, nm_client_first, nbr_client_ssn, 
     cd_client_gender, dt_client_birth 
    FROM client 
    WHERE yr_service_fiscal BETWEEN 2007 AND 2009 
ORDER BY nm_client_last, 
     nm_client_first, 
     nbr_client_ssn, 
     cd_client_gender, 
     dt_client_birth; 

    CURSOR person_cur IS 
    SELECT id_person, nm_person_last, nm_person_first, nbr_person_id_number, 
     cd_person_sex, dt_person_birth 
    FROM person 
    WHERE EXTRACT (YEAR FROM dt_last_update) >= 2007 
    AND nm_person_full != 'Employee,Conversion' 
ORDER BY nm_person_last, 
     nm_person_first, 
     nbr_person_id_number, 
     cd_person_sex, 
     dt_person_birth; 

-- Record for client and person data 
client_rec client_cur%ROWTYPE; 
person_rec person_cur%ROWTYPE;  

-- Record for client_match and person_match 
client_match_rec client_cur%ROWTYPE; 
person_match_rec person_cur%ROWTYPE; 

-- For person data collection- create "table of records" (index-by table type collection) 
TYPE person_t IS TABLE OF person_rec%ROWTYPE INDEX BY BINARY_INTEGER; 
person_tab person_t; 

-- For best client and person matches collections- create "table of records" (index-by table type collection) 
TYPE client_best_matches_t IS TABLE OF client_match_rec%ROWTYPE INDEX BY BINARY_INTEGER; 
client_matches_tab client_best_matches_t; 

TYPE person_best_matches_t IS TABLE OF person_match_rec%ROWTYPE INDEX BY BINARY_INTEGER; 
person_matches_tab person_best_matches_t; 


-- Variables 
v_match_score number DEFAULT 0 
v_temp_score number DEFAULT 0 
v_match_threshold number DEFAULT 0 

BEGIN 

-- Populate the person collection by processing the person cursor rows into the person records 
OPEN person_cur; 
LOOP 
    FETCH person_cur INTO person_rec; 
    EXIT WHEN person_cur%NOTFOUND; 
    person_tab (person_cur%ROWCOUNT) := person_rec; 
    END LOOP; 

-- Process the client cursor rows into the client records 
OPEN client_cur; 
LOOP 
    FETCH client_cur INTO client_rec; 
    EXIT WHEN client_cur%NOTFOUND; 

/* 
Inner loop compares one record in client to each record in person collection 
Save match score in v_temp_score 
Compare v_temp_score to v_match_score to see if this is the best match yet 
If so, save records in best_match_client and best_match_person and save match score in v_match_score 
*/ 
    IF person_tab IS NOT NULL 
    THEN 
    i := person_tab.FIRST; 
    WHILE (i IS NOT NULL) 
    LOOP 
     (case when client_cur.nbr_client_ssn = person_tab.--HOW TO REFERENCE PERSON_TAB.SSN? 
     then) 

     i:= person_tab.NEXT (i); 
     END LOOP; 
    END IF; 

/* 
If a match exists, add it to the collection for match results 
Initialize the records and variables 
*/ 

-- End outer loop 

END LOOP; 

END; 
+0

爲了參考'PERSON_TAB.SSN',您需要更新'person_cur'光標揭露它。你有match_score/temp_score/etc但你不使用它們。我最初的印象是,你不需要你定義的所有類型...... – 2009-10-14 00:55:36

+0

我不確定這是什麼意思 - 「你需要更新person_cur光標以顯示它。」我定義了match_score/temp_score等,因爲我認爲我需要它們來執行比較(我的目標在內部循環之前的註釋部分中進行了解釋),但這又是我的代碼的開始,它們只是佔位符現在。如果有一種方法可以在不定義額外記錄的情況下做到這一點,我會嘗試。 – Julie 2009-10-14 12:42:30

回答

2

你問:

person_tab .--如何引用PERSON_TAB.SSN?

像這樣:

person_tab(i).ssn 
+0

謝謝,這直接回答了我的問題。我假設這意味着我不必指定記錄,因爲表(loop_index)將指向正確的「行」。 – Julie 2009-10-14 12:46:31

+0

沒錯 - person_tab(i)是person_rec%ROWTYPE類型的記錄。 – 2009-10-14 13:29:54

+0

謝謝!這有很大幫助。結合上面David提供的最佳實踐建議,我想我應該能夠弄清楚這一點。 – Julie 2009-10-14 13:32:36

2

這裏的最佳做法是在可行的情況下使用單個SQL語句。從不在PL/SQL中執行SQL中的操作。

在任何情況下,避免明確的遊標,如果你能做到這一點,並使用隱式語法來代替:

For x in (select table_name from user_tables) 
Loop 
    other_variable = x.table_name; 
    etc. ..... 
End Loop; 
+0

如果我使用上面的定義隱式遊標,我是否仍然需要定義一條記錄?或者我只是使用表(loop_index)?如果可以使用表(loop_index)引用表的「記錄」,何時定義記錄與表? – Julie 2009-10-14 12:50:23

+0

使用此隱式遊標語法,您將只循環記錄中的每一行。我建議瀏覽文檔以獲取有關屬性的更多信息,但是您不必創建要選擇的記錄。 – 2009-10-14 23:31:04

相關問題