我正在学习 pl/sql,并且有一个使用游标和过程或函数的练习。该练习需要使用从其他三个表获取数据的游标将数据插入表(这将是支持/视图表)。
查找下表:
CREATE TABLE t_csc (
nr_csc NUMBER NOT NULL,
nr_client NUMBER(10) NOT NULL,
cd_product NUMBER(10) NOT NULL,
cd_employee NUMBER(10),
ds_detail_csc CLOB,
dt_open_csc DATE,
hr_open_csc NUMBER(2),
dt_service DATE,
hr_service NUMBER(2),
nr_time_total_csc NUMBER(10),
ds_detail_retorn_csc CLOB,
tp_csc CHAR(1) NOT NULL,
st_csc CHAR(1),
nr_index_satisfaction NUMBER(2));
CREATE TABLE t_product (
cd_product NUMBER(10) NOT NULL,
cd_category NUMBER NOT NULL,
nr_cd_bar_prod VARCHAR2(50),
ds_product VARCHAR2(80) NOT NULL,
vl_unitary NUMBER(8, 2) NOT NULL,
tp_pack VARCHAR2(15),
st_product CHAR(1),
vl_perc_profit NUMBER(8, 2),
ds_complete_prod VARCHAR2(4000) NOT NULL);
CREATE TABLE t_category_prod (
cd_category NUMBER NOT NULL,
tp_category CHAR(1) NOT NULL,
ds_category VARCHAR2(500) NOT NULL,
dt_start DATE,
dt_end DATE,
st_category CHAR(1) NOT NULL);
查看表格:
CREATE TABLE t_ocurrence (
nr_ocurrence_csc NUMBER NOT NULL,
dt_open_csc DATE,
hr_open_csc NUMBER(2),
ds_type_classific_csc VARCHAR2(30) NOT NULL,
ds_index_satisfac_atd_csc VARCHAR2(30),
cd_category_prod NUMBER NOT NULL,
nm_type_category_prod VARCHAR2(25) NOT NULL,
ds_category_prod VARCHAR2(500) NOT NULL,
cd_product NUMBER(10),
ds_product VARCHAR2(80) NOT NULL,
tp_pack VARCHAR2(15));
我尝试了这段代码但没有成功:
DECLARE
csc_ocurr t_ocurrence%ROWTYPE; -- Declarando uma variável que vai conter T_MC_SGV_OCORRENCIA
CURSOR cur_search IS -- Cria um cursor chamado cur_search do tipo SELECT
SELECT CSC.nr_CSC, CSC.dt_open_csc, CSC.hr_open_csc, CSC.tp_csc, CSC.nr_index_satisfaction, CATPROD.cd_category,
CATPROD.tp_category, CATPROD.ds_category, PROD.cd_product, PROD.ds_product, PROD.tp_pack, PROD.vl_unitary, PROD.vl_perc_profit
FROM t_csc CSC, t_category_prod CATPROD, t_product PROD
WHERE CATPROD.cd_category = PROD.cd_category AND PROD.cd_product = CSC.cd_product;
BEGIN
OPEN cur_search;
LOOP
FETCH cur_search INTO csc_ocurr.nr_ocurrence_csc, csc_ocurr.dt_open_csc, csc_ocurr.hr_open_csc,
csc_ocurr.ds_type_classific_csc, csc_ocurr.ds_index_satisfac_atd_csc, csc_ocurr.cd_category_prod, csc_ocurr.nm_type_category_prod,
csc_ocurr.ds_category_prod, csc_ocurr.cd_product, csc_ocurr.ds_product, csc_ocurr.tp_pack; -- 20
EXIT WHEN cur_search%notfound;
INSERT INTO t_ocurrence VALUES (csc_ocurr.nr_ocurrence_csc, csc_ocurr.dt_open_csc, csc_ocurr.hr_open_csc,
csc_ocurr.ds_type_classific_csc, csc_ocurr.ds_index_satisfac_atd_csc, csc_ocurr.cd_category_prod, csc_ocurr.nm_type_category_prod,
csc_ocurr.ds_category_prod, csc_ocurr.cd_product, csc_ocurr.ds_product, csc_ocurr.tp_pack);
END LOOP;
CLOSE cur_search;
END;
/
如果您编写的查询返回所需的结果(我不能告诉;您发布的语句不包含任何引用完整性约束,并且没有示例数据),那么一个更简单选项是使用游标
FOR
循环,因为您不必声明游标变量,打开游标,获取,注意退出循环并关闭游标 - Oracle 会为您完成这些工作。
另请注意,
INSERT INTO
应始终包含您要插入的所有列。它需要更多的输入,但非常清楚(什么被插入到哪一列中)。
INSERT INTO
你写的不行;如果选择了nr_csc
,则不能插入nr_ocurrence_csc
,也必须是nr_csc
。对于其他一堆列也是如此。
最后,在连接表时,明确地 - 使用
JOIN
。如果您在 FROM
子句中命名所有表并在 WHERE
中 join它们,它会起作用(它像这样工作很长时间),但是 - 我们不再生活在 1990 年代了。为可能的条件/过滤器保留
WHERE
子句。
因此:
SQL> BEGIN
2 FOR csc_ocurr
3 IN (SELECT csc.nr_csc,
4 csc.dt_open_csc,
5 csc.hr_open_csc,
6 csc.tp_csc,
7 csc.nr_index_satisfaction,
8 catprod.cd_category,
9 catprod.tp_category,
10 catprod.ds_category,
11 prod.cd_product,
12 prod.ds_product,
13 prod.tp_pack
14 FROM t_category_prod catprod
15 JOIN t_product prod
16 ON catprod.cd_category = prod.cd_category
17 JOIN t_csc csc ON csc.cd_product = prod.cd_product)
18 LOOP
19 INSERT INTO T_OCURRENCE (nr_ocurrence_csc,
20 dt_open_csc,
21 hr_open_csc,
22 ds_type_classific_csc,
23 ds_index_satisfac_atd_csc,
24 cd_category_prod,
25 nm_type_category_prod,
26 ds_category_prod,
27 cd_product,
28 ds_product,
29 tp_pack)
30 VALUES (csc_ocurr.nr_csc,
31 csc_ocurr.dt_open_csc,
32 csc_ocurr.hr_open_csc,
33 csc_ocurr.tp_csc,
34 csc_ocurr.nr_index_satisfaction,
35 csc_ocurr.cd_category,
36 csc_ocurr.tp_category,
37 csc_ocurr.ds_category,
38 csc_ocurr.cd_product,
39 csc_ocurr.ds_product,
40 csc_ocurr.tp_pack);
41 END LOOP;
42 END;
43 /
PL/SQL procedure successfully completed.
SQL>
我第二次尝试,但现在我在过程中声明了变量。之后,我使用游标从表
T_CSC
、T_PRODUCT
T_CATEGORY_PROD
获取数据,打开游标后,我将数据 FETCH
放入声明的变量中,并使用它们来填充 INSERT INTO
桌子。T_OCURRENCE