我正在编写一个PL / SQL包来填充表,它将根据公式计算几个指标(从不同的表中查询),但我最终得到的包中充满了来自不同表的select语句。 有没有其他方法可以将所有这些查询聚合在一起而不会使代码过于复杂(我喜欢简单)。
请建议。
- 陷入困境的开发者
答案 0 :(得分:0)
使用游标。例如,您可能想要一个接一个地编写一堆语句,例如:
DECLARE
nCurrent_balance CUSTOMER_RUNNING_BALANCE.CURRENT_BALANCE%TYPE;
nTotal_credit_line CUSTOMER_CREDIT_LINE.TOTAL_CREDIT_LINE%TYPE;
nAvailable_credit CUSTOMER_CREDIT_LINE.AVAILABLE_CREDIT%TYPE;
strLocation_name CUSTOMER_ADDRESS.LOCATION_NAME%TYPE;
strStreet_address_1 CUSTOMER_ADDRESS.STREET_ADDRESS_1%TYPE;
strCity CUSTOMER_ADDRESS.CITY%TYPE;
strState CUSTOMER_ADDRESS.CITY%TYPE;
strZip CUSTOMER_ADDRESS.CITY%TYPE;
BEGIN
FOR aRow IN (SELECT CUSTOMER_ID FROM CUSTOMER)
LOOP
BEGIN
SELECT CURRENT_BALANCE
INTO nCurrent_balance
FROM CUSTOMER_RUNNING_BALANCE rb
WHERE rb.CUSTOMER_ID = aRow.CUSTOMER_ID;
EXCEPTION
WHEN NO_DATA_FOUND THEN
nCurrent_balance := NULL;
END;
BEGIN
SELECT TOTAL_CREDIT_LINE, AVAILABLE_CREDIT
INTO nTotal_credit_Line, nAvailable_credit
FROM CUSTOMER_CREDIT_LINE cl
WHERE cl.CUSTOMER_ID = aRow.CUSTOMER_ID;
EXCEPTION
WHEN NO_DATA_FOUND THEN
nTotal_credit_line := NULL;
nAvailable_credit := NULL;
END;
BEGIN
SELECT LOCATION_NAME,
STREET_ADDRESS_1,
CITY,
STATE,
ZIP
INTO strLocation_name,
strStreet_address_1,
strCity,
strState,
strZip
FROM CUSTOMER_ADDRESS ca
WHERE ca.CUSTOMER_ID = aRow.CUSTOMER_ID AND
ca.ADDRESS_TYPE = 'HEADQUARTERS';
EXCEPTION
WHEN NO_DATA_FOUND THEN
strLocation_name := NULL;
strStreet_address_1 := NULL;
strCity := NULL;
strState := NULL;
strZip := NULL;
END;
// Do something useful with the data here
END LOOP;
END;
伊克。这里我们有一个游标和一堆单独的SELECT语句,将来自三个额外源的数据拉入单独声明的变量中。这里有很多代码行,但大部分代码都没用 - 除了由于编写方式所有这些都是必需的 - AND 这是一个巨大的,明显的,可能致命的编码错误在这个,虽然代码可能运行得很好 - 你能发现吗? : - )
使用游标将表连接在一起会大大减少代码量,消除对所有这些异常处理程序的需要,并且完全消除了产生上述错误的机会:
BEGIN
FOR aRow IN (SELECT c.CUSTOMER_ID,
rb.CURRENT_BALANCE,
cl.TOTAL_CREDIT_LINE,
cl.AVAILABLE_CREDIT,
ca.LOCATION_NAME,
ca.STREET_ADDRESS_1,
ca.CITY,
ca.STATE,
ca.ZIP
FROM CUSTOMER c
LEFT OUTER JOIN CUSTOMER_RUNNING_BALANCE rb
ON rb.CUSTOMER_ID = c.CUSTOMER_ID
LEFT OUTER JOIN CUSTOMER_CREDIT_LINE cl
ON cl.CUSTOMER_ID = c.CUSTOMER_ID
LEFT OUTER JOIN CUSTOMER_ADDRESS ca
ON ca.CUSTOMER_ID = c.CUSTOMER_ID AND
ca.ADDRESS_TYPE = 'HEADQUARTERS')
LOOP
// Do something useful with the data here
END LOOP;
END;
所以 - 第一个例子中的59行代码,而第二个代码中的代码是22行。在第二个例子中,光标清楚地说明了表之间的关系。第一个例子中的错误(我写的时候实际上做的经典剪切和粘贴错误:-)在第二个例子中是不可能的。
构建关系数据库以快速有效地处理第二个示例中的游标等查询。通过使用查询,您可以减少
的次数