PLSQL集合 - 创建一个记录集合还是不是?
我是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;
这里的最佳做法是在可行的情况下使用单个SQL语句。从不在PL/SQL中执行SQL中的操作。
在任何情况下,避免明确的游标,如果你能做到这一点,并使用隐式语法来代替:
For x in (select table_name from user_tables)
Loop
other_variable = x.table_name;
etc. .....
End Loop;
如果我使用上面的定义隐式游标,我是否仍然需要定义一条记录?或者我只是使用表(loop_index)?如果可以使用表(loop_index)引用表的“记录”,何时定义记录与表? – Julie 2009-10-14 12:50:23
使用此隐式游标语法,您将只循环记录中的每一行。我建议浏览文档以获取有关属性的更多信息,但是您不必创建要选择的记录。 – 2009-10-14 23:31:04
为了参考'PERSON_TAB.SSN',您需要更新'person_cur'光标揭露它。你有match_score/temp_score/etc但你不使用它们。我最初的印象是,你不需要你定义的所有类型...... – 2009-10-14 00:55:36
我不确定这是什么意思 - “你需要更新person_cur光标以显示它。”我定义了match_score/temp_score等,因为我认为我需要它们来执行比较(我的目标在内部循环之前的注释部分中进行了解释),但这又是我的代码的开始,它们只是占位符现在。如果有一种方法可以在不定义额外记录的情况下做到这一点,我会尝试。 – Julie 2009-10-14 12:42:30