Страница 1 из 1

Ошибка: Ошибка создания FUNCTION S$FN_OPGETCOLOR

Добавлено: 22 сен 2014, 11:26
Zver
Уважаемые форумчане,

Как это обычно бывает, в один прекрасный день при сборке проекта появилась новая ошибка:

Ошибка: Ошибка создания FUNCTION S$FN_OPGETCOLOR C:\workspace\Source\EPA_MnPlan\dsql\StoredFunc\OperPlanFunc.vip(стр. 166, поз. 1)

У коллеги этот проект собирается без ошибки. Конкретно этот файл используется уже давно и никаких изменений по нему нет (используем SVN, так что можно гарантировать).
Хотелось бы в первую очередь понять, на что ругается компилятор.

Вот исходный текст:

Код: Выделить всё

!#include FldColor.inc

SQL Function fn_OpGetColor(ptMnPlan: word; pcMnPlan: comp; pcSpMnPl: comp; pDemand: double; pcOAT2Analogs: comp): integer;
var
 res     : integer;
 qty     : double;
 balance : double;
 prior_1 : comp;  // красный  (не обеспечено)
 prior_2 : comp;  // желтый   (срыв срока)
 prior_3 : comp;  // какой-то (обеспечено из остатков и предложения)
 prior_4 : comp;  // зеленый  (обеспечено только из остатков)
{
  // теперь эти цифры не являются константами цветов, теперь это приоритеты (по идее, функцию надо бы тоже переименовать, но лишней возни не хочется)
  prior_1  := 1;
  prior_2  := 2;
  prior_3  := 3;
  prior_4  := 4;

  // cсумарный остаток по ячейке
  balance :=
   COALESCE(
     (
            SELECT
                SUM(CASE WHEN SpObjAcc.KolcFact > 0 THEN SpObjAcc.KolcFact ELSE 0 END)
            FROM
                ObjAccT
            JOIN SpObjAcc
              ON (  MpGetTypeSpec(
                     ObjAccT.TypeOwn) = SpObjAcc.TypeObj
                  AND pcSpMnPl        = SpObjAcc.cObject
                  AND ObjAccT.Nrec    = SpObjAcc.cObjAccT
                )
            WHERE
                ObjAccT.TypeOwn = ptMnPlan
            AND ObjAccT.cOwner  = pcMnPlan
            AND ObjAccT.KindRec = 1
       ),0);
  // остатки по аналогам
  if (pcOAT2Analogs <> #comp(0))
  {
     balance := balance +  COALESCE(
      (SELECT
           SUM(SpObjAcc.KolcPos)
       FROM
           SpObjAcc
       WHERE
           SpObjAcc.TypePos  = MpGetTypeSpec(ptMnPlan)
       AND SpObjAcc.cPos     = pcSpMnPl
       AND SpObjAcc.cObjAccT = pcOAT2Analogs
       AND SpObjAcc.TypeHier = 0 )
     ,0);
  }

  // Если остаток больше или равен спросу, значит спрос полностью покрыт остатком
  if (balance >= pDemand)
     return prior_4;

  // Количество предложения (если с минусом, значит было предложение позже спроса)
  qty :=
   COALESCE(
    (
        SELECT
          SUM(SOA1_In.KolcPos)
        * (CASE WHEN SUM(CASE WHEN SOA0_In.StartDate > SOA1_In.StartDate THEN 1 ELSE 0 END) > 0 THEN -1 ELSE 1 END) AS FLFAILURE
        FROM
          ObjAccT OAT_Cur
        JOIN SpObjAcc SOA1_Cur ON
        (
               MpGetTypeSpec(
                 OAT_Cur.TypeOwn
                  )            = SOA1_Cur.TypeObj
           AND pcSpMnPl        = SOA1_Cur.cObject
           AND OAT_Cur.Nrec    = SOA1_Cur.cObjAccT
        )

        JOIN ObjAccT OAT_In ON
        (
               OAT_Cur.TypeObj = OAT_In.TypeOwn
           AND OAT_Cur.cObject = OAT_In.cOwner
           AND 1               = OAT_In.KindRec
           AND 2               = OAT_In.CondRec
        )
        JOIN SpObjAcc SOA1_In
          JOIN SpObjAcc SOA0_In ON
           (
                SOA1_In.cSpObjAcc = SOA0_In.Nrec
           )
        ON
        ( MpGetTypeSpec(
              OAT_In.TypeOwn) = SOA1_In.TypeObj
           AND SOA1_Cur.cPos  = SOA1_In.cObject
           AND OAT_In.Nrec    = SOA1_In.cObjAccT
        )
        WHERE
        (
              ptMnPlan = OAT_Cur.TypeOwn
          AND pcMnPlan = OAT_Cur.cOwner
          AND 1        = OAT_Cur.KindRec
        )
   ), 0
  )

  RETURN (
    CASE WHEN balance + ABS(qty) >= pDemand
      THEN
        (CASE WHEN qty > 0 THEN prior_3 ELSE prior_2 END)
      ELSE
         prior_1
      END
   );
}

/*
SQL Function fnOp_IsFailurePeriod(ptMnPlan: word; pcMnPlan: comp; pcSpMnPl: comp): double;
var
 res : integer;
{
  res :=
   COALESCE(
    (
        SELECT
          SUM(SOA1_In.KolcPos) * (CASE WHEN SUM(CASE WHEN SOA0_In.StartDate > SOA1_In.StartDate THEN 1 ELSE 0 END) > 0 THEN -1 ELSE 1 END)  AS FLFAILURE
        FROM
          ObjAccT OAT_Cur
        JOIN ObjAccT OAT_In ON
        (
               OAT_Cur.TypeObj = OAT_In.TypeOwn
           AND OAT_Cur.cObject = OAT_In.cOwner
           AND 1               = OAT_In.KindRec
           AND 2               = OAT_In.CondRec
        )
        JOIN SpObjAcc SOA1_Cur ON
        (
               MpGetTypeSpec(
                 OAT_Cur.TypeOwn
                  )            = SOA1_Cur.TypeObj
           AND pcSpMnPl        = SOA1_Cur.cObject
           AND OAT_Cur.Nrec    = SOA1_Cur.cObjAccT
        )

        JOIN SpObjAcc SOA1_In
          JOIN SpObjAcc SOA0_In ON
           (
              SOA1_In.cSpObjAcc = SOA0_In.Nrec
           )
        ON
        (
               MpGetTypeSpec(
                 OAT_In.TypeOwn
                 )            = SOA1_In.TypeObj
           AND SOA1_Cur.cPos  = SOA1_In.cObject
           AND OAT_In.Nrec    = SOA1_In.cObjAccT
        )
        WHERE
        (
              ptMnPlan = OAT_Cur.TypeOwn
          AND pcMnPlan = OAT_Cur.cOwner
          AND 1        = OAT_Cur.KindRec
        )
   ), 0
  )

  return (CASE WHEN res > 0 THEN 1 ELSE 0 END);
}
*/

Re: Ошибка: Ошибка создания FUNCTION S$FN_OPGETCOLOR

Добавлено: 22 сен 2014, 11:40
Den
а в Ms70|Ora70.log ничего не пишут при этом ?

Re: Ошибка: Ошибка создания FUNCTION S$FN_OPGETCOLOR

Добавлено: 22 сен 2014, 12:11
Zver
Den, огромное спасибо, помогло.

Вот результат расследования:
В ms70drv.log было сообщение, что для пользователя запрещено Create function.
Как оказалось,мне случайно порезали права на базу.

Re: Ошибка: Ошибка создания FUNCTION S$FN_OPGETCOLOR

Добавлено: 22 сен 2014, 14:29
zna
На мой взгляд, проще создать vip- запросом пустую функцию, а содержанием наполнить из SQL Management Studio "Alter Function...
Но права, конечно, должны быть и в этом случае.