2015-04-15 110 views
-1

我正在写一个plsql函数,在这个函数中我想添加一个游标。游标取决于其中一个表的值。 如果我在光标前写了任何东西,它会给我错误。 如何写这个。 以下是我的示例代码。带光标的plsql函数

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; 

如果我提供选择语句之前,它的光标工作。 由我的案例陈述取决于我的选择。 如何做到这一点。 请帮忙。

回答

0

您不能在begin之前有selectcase;他们不属于声明部分。你可以在每个子块中定义每个游标,但是你也必须在每个子块中重复循环代码。

而不是定义两个游标,你可以做一个连接来决定检查哪一列。像这样(未经):

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 
... 

或者,如果你愿意的话,因为你的两个原始游标除了过滤器值相同,你可以(如你所说)做选择分开,然后通过该值一个parameratised光标:

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的区别。

+0

感谢您的回复......我不能在开始之前声明游标....然后编写我的选择语句,然后在案例中为游标赋值....导致上面的代码只是小样本。 ..我将需要从差异表中获取数据...所以不可能写入加入... – user1515118

+0

@ user1515118 - 是的,我已经用示例更新了我的答案。尽管如此,我仍然认为除了过滤器值之外,两个游标是相同的。如果它们实际上根据范围头数据加入不同的表,那么它会变得更加复杂,并且您可能需要切换到open-fetch-close方法而不是简单的游标for-loop。 –