我正在编写一个plsql函数,在这个函数中我要添加一个游标。 cursor取决于其中一个表的值。 如果我在光标前写任何东西它给我错误。 怎么写。 以下是我的示例代码。
CREATE OR REPLACE FUNCTION F_ResolveValueExpression(inRowId NUMBER)
RETURN VARCHAR2 IS
isRangeValue PLS_INTEGER;
ExpressionValue VARCHAR2(100);
FinalRangeValue VARCHAR2(100);
g_ExchangeType VARCHAR2(100) := 'BSE';
g_TradeMode VARCHAR2(100) := 'SQUP';
rangeTypeNrageField VARCHAR2(10);
SELECT RANGE_TYPE || ' ' || Range_field
INTO rangeTypeNrageField
FROM Range_Header
WHERE RANGE_ID = inRowId;
CASE rangeTypeNrageField
WHEN 'RL EXCHANGE' THEN
CURSOR c_RangeValueDetails IS
SELECT R.LOV_VALUE LOV_VALUE,
R.RANGE_VAL_TYPE RANGE_VAL_TYPE,
R.RANGE_VALUE RANGE_VALUE
FROM Range_Value_Details R
WHERE R.RANGE_ID = inRowId
AND R.LOV_VALUE = g_ExchangeType;
WHEN 'RL TRDMODE' THEN
CURSOR c_RangeValueDetails IS
SELECT R.LOV_VALUE LOV_VALUE,
R.RANGE_VAL_TYPE RANGE_VAL_TYPE,
R.RANGE_VALUE RANGE_VALUE
FROM Range_Value_Details R
WHERE R.RANGE_ID = inRowId
AND R.LOV_VALUE = g_TradeMode;
END CASE;
BEGIN
FOR i IN c_RangeValueDetails
LOOP
IF i.RANGE_VAL_TYPE = 'R' THEN
ExpressionValue := F_ResolveValueExpression(i.RANGE_VALUE);
ELSE
ExpressionValue := i.RANGE_VALUE;
END IF;
End Loop;
RETURN FinalRangeValue;
END;
如果我在光标工作之前提交select语句。 我的案例陈述取决于我的选择。 如何实现这一目标。 请帮忙。
答案 0 :(得分:0)
您不能在select
之前拥有case
或begin
;它们不属于声明部分。您可以在自己的子块中定义每个游标,但是您也必须在每个子块中重复循环代码。
您可以执行连接以决定要检查的列,而不是定义两个游标。像这样(未经测试):
CREATE OR REPLACE FUNCTION F_ResolveValueExpression(inRowId NUMBER)
RETURN VARCHAR2 IS
isRangeValue PLS_INTEGER;
ExpressionValue VARCHAR2(100);
FinalRangeValue VARCHAR2(100);
g_ExchangeType VARCHAR2(100) := 'BSE';
g_TradeMode VARCHAR2(100) := 'SQUP';
CURSOR c_RangeValueDetails IS
SELECT R.LOV_VALUE LOV_VALUE,
R.RANGE_VAL_TYPE RANGE_VAL_TYPE,
R.RANGE_VALUE RANGE_VALUE
FROM Range_Header H
JOIN Range_Value_Details R
ON R.RANGE_ID = H.RANGE_ID
AND ((H.RANGE_TYPE = 'RL' AND H.Range_field = 'EXCHANGE'
AND R.LOV_VALUE = g_ExchangeType)
OR (H.RANGE_TYPE = 'RL' AND H.Range_field = 'TRDMODE'
AND R.LOV_VALUE = g_TradeMode))
WHERE H.RANGE_ID = inRowId;
BEGIN
FOR i IN c_RangeValueDetails
...
或者如果您愿意,因为除了过滤器值之外,您的两个原始游标是相同的,您可以(按照建议)单独执行选择,然后将该值传递给参数化游标:
CREATE OR REPLACE FUNCTION F_ResolveValueExpression(inRowId NUMBER)
RETURN VARCHAR2 IS
isRangeValue PLS_INTEGER;
ExpressionValue VARCHAR2(100);
FinalRangeValue VARCHAR2(100);
g_ExchangeType VARCHAR2(100) := 'BSE';
g_TradeMode VARCHAR2(100) := 'SQUP';
rangeTypeNrageField VARCHAR2(10);
CURSOR c_RangeValueDetails (c_rangeTypeNrageField varchar2) IS
SELECT R.LOV_VALUE LOV_VALUE,
R.RANGE_VAL_TYPE RANGE_VAL_TYPE,
R.RANGE_VALUE RANGE_VALUE
FROM Range_Value_Details R
WHERE R.RANGE_ID = inRowId
AND R.LOV_VALUE = CASE c_rangeTypeNrageField
WHEN 'RL EXCHANGE' THEN g_ExchangeType
WHEN 'RL TRDMODE' THEN g_TradeMode END;
BEGIN
SELECT RANGE_TYPE || ' ' || Range_field
INTO rangeTypeNrageField
FROM Range_Header
WHERE RANGE_ID = inRowId;
FOR i IN c_RangeValueDetails (rangeTypeNrageField)
...
或者先用以下方法评估案例陈述:
...
CURSOR c_RangeValueDetails (c_lov_value varchar2) IS
SELECT R.LOV_VALUE LOV_VALUE,
R.RANGE_VAL_TYPE RANGE_VAL_TYPE,
R.RANGE_VALUE RANGE_VALUE
FROM Range_Value_Details R
WHERE R.RANGE_ID = inRowId
AND R.LOV_VALUE = c_lov_value;
BEGIN
SELECT RANGE_TYPE || ' ' || Range_field
INTO rangeTypeNrageField
FROM Range_Header
WHERE RANGE_ID = inRowId;
FOR i IN c_RangeValueDetails (CASE rangeTypeNrageField
WHEN 'RL EXCHANGE' THEN g_ExchangeType
WHEN 'RL TRDMODE' THEN g_TradeMode END)
...
您可以使用隐式游标进行循环而不是显式(在声明部分中)游标; see the documentation了解差异。