【发布时间】:2020-09-09 06:38:52
【问题描述】:
我正在尝试使用两组数据构建一个基于星型模式的数据仓库,其中包含 5 个维度表和 1 个事实表,MASTERDATA 包含 100 条记录,DATASTREAM 包含 10,000 条记录。
我正在从 DATASTREAM 读取 100 条记录作为游标的输入,然后逐条读取游标记录,然后从索引 product_id 上的 MASTERDATA 检索相关记录作为索引嵌套循环连接。在此之后,我从相关维度和事实表中的事务元组加载新属性。
但是,我有一些错误。我只是在寻求帮助以了解为什么我会遇到我遇到的错误。目前的错误是:
Error(98,6):PL/SQL:SQL Statement Ignored
Error(101,5):PL/SQL: ORA-00933: SQL command not properly ended
Error(105,8):PLS-00103:Encountered the symbol "LOOP" when expecting one of the following: if
Error(113):PLS-00103:Encountered the symbol "end-of-file" when expecting one of the following: ;
我的代码:
CREATE OR REPLACE PROCEDURE transactionINLJ AS TYPE t_cursor is ref cursor;
v_cursor t_cursor;
v_cursor_records DATASTREAM%rowtype;
record_100 varchar2(300);
rec number;
v_customer_id masterdata.customer_id%type;
v_customer_account_type masterdata.customer_account_type%type;
v_product_id masterdata.product_id%type;
v_product_name masterdata.product_name%type;
v_supplier_id masterdata.supplier_id%type;
v_supplier_name masterdata.supplier_name%type;
v_outlet_id masterdata.outlet_id%type;
v_outlet_name masterdata.outlet_name%type;
v_sale_price masterdata.sale_price%type;
t_customer_id int;
t_supplier_id int;
t_product_id int;
t_outlet_id int;
t_date_id int;
t_sales_fact int;
BEGIN
rec := 1;
WHILE (rec <= 10000)
LOOP
record_100 := 'SELECT * FROM datastream WHERE datastream_id between '|| TO_CHAR(rec) ||
' and ' || TO_CHAR(rec+99);
OPEN v_cursor FOR record_100;
LOOP
FETCH v_cursor INTO v_cursor_records;
EXIT WHEN v_cursor%notfound;
SELECT product_id, product_name, supplier_id, supplier_name, sale_price
INTO v_product_id, v_product_name, v_supplier_id, v_supplier_name, v_sale_price
FROM masterdata
WHERE product_id = v_cursor_records.product_id;
SELECT COUNT(0)
INTO t_product_id
FROM product_dim
WHERE product_id = v_cursor_records.product_id;
IF t_product_id = 0 THEN
INSERT INTO product_dim(product_id, product_name)
VALUES (v_cursor_records.product_id, v_cursor_records.product_name);
END IF;
SELECT COUNT(0)
INTO t_customer_id
FROM customer_dim
WHERE customer_id = v_cursor_records.customer_id;
IF t_customer_id = 0 THEN
INSERT INTO customer_dim(customer_id, customer_name,customer_account_type)
VALUES (v_cursor_records.customer_name, v_cursor_records.customer_account_type, v_cursor_records.customer_account_type);
END IF;
SELECT COUNT(0)
INTO t_supplier_id
FROM supplier_dim
WHERE supplier_id = v_cursor_records.supplier_id;
IF t_supplier_id = 0 THEN
INSERT INTO supplier_dim(supplier_id, supplier_name)
VALUES (v_cursor_records.supplier_id, v_cursor_records.supplier_name);
END IF;
SELECT COUNT(0)
INTO t_outlet_id
FROM outlet_dim
WHERE outlet_id = v_cursor_records.outlet_id;
IF t_outlet_id = 0 THEN
INSERT INTO outlet_dim(outlet_id, outlet_name)
VALUES (v_cursor_records.outlet_id, v_cursor_records.outlet_name);
END IF;
SELECT COUNT(0)
INTO t_date_id
FROM date_dim
WHERE d_date = v_cursor_records.d_date;
IF t_date_id = 0 THEN
INSERT INTO date_dim(d_date, d_year, d_quater, d_month, d_day)
VALUES (v_cursor_records.d_date
,EXTRACT(year FROM v_cursor_records.d_date), TO_CHAR(v_cursor_records.d_date,'Q')
,EXTRACT(month FROM v_cursor_records.d_date)
,EXTRACT(day FROM v_cursor_records.d_date));
END IF;
SELECT COUNT(0)
INTO t_sales_fact
FROM sales_fact
WHERE product_id = v_cursor_records.product_id
AND customer_id = v_csr_rec.customer_id
AND supplier_id = v_csr_rec.supplier_id
AND outlet_id = v_csr_rec.outlet_id
AND d_date = v_csr_rec.d_date
AND sale_price = v_csr_rec.sale_price
AND quantity_sold = v_csr_rec.quantity_sold;
IF t_sales_fact = 0 THEN
INSERT INTO sales_fact(customer_id,product_id,outlet_id,supplier_id,d_date,sale_price,total_sale,quantity_sold)
VALUES (v_cursor_records.customer_id, v_cursor_records.product_id, v_cursor_records.outlet_id,v_cursor_records.supplier_id,
v_cursor_records.d_date, v_cursor_records.sale_price, v_cursor_records.quantity_sold*sale_price, v_cursor_records.quantity_sold)
END IF;
COMMIT;
END LOOP;
CLOSE v_cursor;
COMMIT;
rec := rec+100;
END LOOP;
END;
【问题讨论】:
-
最后一个
INSERT INTO语句末尾缺少分号。 -
谢谢,我在再次阅读我的代码后修复了这个错误和其他一些错误,但现在我有更多错误,例如:PLS00302:必须声明组件“PRODUCT_NAME”。你知道为什么没有声明这个组件吗?
-
可能 MASTER_DATA.PRODUCT_NAME 列不存在,或者它存在于不同的架构中,或者您的用户没有直接访问它的权限。但是您可能想重新开始并尝试构建一个最小可行的程序,而不是构建所有内容然后调试所有错误。
-
顺便说一下,光标不需要是动态的。使用静态游标,您可以切换到更简单的
for r in (select...) loop语法,这将在一定程度上简化代码。如果性能是一个问题,那么每行上每个值的计数也是低效的。虽然它不会有任何区别,但为什么count(0)而不是标准的count(*)?