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

Прямой SQL

Добавлено: 10 сен 2010, 18:59
Alex_R
Осваиваю DSQL, на данный момент имею следующий работающий запрос:

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

//=============================================================
interface Test_DSQL 'Test_DSQL';
//-------------------------------------------------------------
table struct mt
(
 dsaldo   : date,
 cmc      : comp,
 cpodr    : comp,
 cparty   : comp
)
;
//--------------------------------------------------------------
create view
 as select
  *
from
  mt
;
//--------------------------------------------------------------
browse brMT;
  show at(,1,,10);
  table mt;
fields
 dsaldo   : [10], protect, noDel;
 cmc      : [17], protect, noDel;
 cpodr    : [17], protect, noDel;
 cparty   : [17], protect, noDel;
end;
handleEvent
cmInit:
{
  var stmt : longInt;
  stmt := sqlAllocStmt;
  sqlBindCol(stmt, 1, dsaldo);
  sqlBindCol(stmt, 2, cmc);
  sqlBindCol(stmt, 3, cpodr);
  sqlBindCol(stmt, 4, cparty);
  sqlExecStmt(stmt, 'SELECT max(saldomc.dsaldo), saldomc.cmc, saldomc.cpodr, saldomc.cparty FROM saldomc where kol < 60000 group by saldomc.cmc, saldomc.cpodr, saldomc.cparty order by saldomc.cmc, saldomc.cpodr, saldomc.cparty');
  sqlFetchInto(stmt, tnmt);
}
//-------------------------------------------------------------
end;
end.
 
подскажите как изменить запрос (привязать базы), чтоб вместо saldomc.cmc получать имя МЦ, вместо saldomc.cpodr название склада, как условие kol < 60000 заменить условием 0000000000000000h<>saldomc.cpary (не хочет сравнивать тип comp), можно ли в выборке использовать результаты работы стандарных интерфейсов выбора (тоесть привязывать word(1)  /==   Pick.wList and   KatMC.NRec  /==   Pick.cRec) и как это правиль делать.

Re: Прямой SQL

Добавлено: 10 сен 2010, 20:52
Vik
Попробуйте либо так:

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

  var strHandle : longInt;

  SQLAddStr(strHandle, 'SELECT')
  SQLAddStr(strHandle, '        MAX(SaldoMc.dSaldo)')
  SQLAddStr(strHandle, '      , KatMc.Name')
  SQLAddStr(strHandle, '      , COALESCE(KatPodr.Name, '''')')
  SQLAddStr(strHandle, '  FROM')
  SQLAddStr(strHandle, '      SaldoMc')
  SQLAddStr(strHandle, '  LEFT JOIN KatMc ON')
  SQLAddStr(strHandle, '    (')
  SQLAddStr(strHandle, '        SaldoMc.cMc = KatMc.Nrec')
  SQLAddStr(strHandle, '    )')
  SQLAddStr(strHandle, '  LEFT JOIN KatPodr ON')
  SQLAddStr(strHandle, '    (')
  SQLAddStr(strHandle, '        SaldoMc.cPodr = KatPodr.Nrec')
  SQLAddStr(strHandle, '    )')
  SQLAddStr(strHandle, '  WHERE')
  SQLAddStr(strHandle, '        SaldoMc.cMc IN (SELECT Pick.cRec FROM Pick WHERE Pick.wList = 1)')
  SQLAddStr(strHandle, '    AND SaldoMc.cParty <> #comp(0)')
  SQLAddStr(strHandle, '  GROUP BY')
  SQLAddStr(strHandle, '    KatMc.Name')
  SQLAddStr(strHandle, '  , KatPodr.Name')
  SQLAddStr(strHandle, '  ORDER BY')
  SQLAddStr(strHandle, '    KatMc.Name')
  SQLAddStr(strHandle, '  , KatPodr.Name')

  sqlPrepare(stmt, strHandle)
  sqlFetchInto(stmt, tnMt);
Либо так:

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

 SQL SELECT
        MAX(SaldoMc.dSaldo)
      , KatMc.Name
      , COALESCE(KatPodr.Name, '')
  FROM
      SaldoMc
  LEFT JOIN KatMc on
    (
        SaldoMc.cMc = KatMc.Nrec
    )
  LEFT JOIN KatMc on
    (
        SaldoMc.cPodr = KatPodr.Nrec
    )
  WHERE
       SaldoMc.cParty <> Comp(0)
  GROUP BY
    KatMc.Name
  , KatPodr.Name
  ORDER BY
    KatMc.Name
  , KatPodr.Name
 INTO Mt

Re: Прямой SQL

Добавлено: 10 сен 2010, 21:03
Vik
как изменить запрос (привязать базы)
А вот это я не понял, что вы имели ввиду. И еще: постов на тему "Прямой SQL" уже много открыто, можно было там спрашивать)

Re: Прямой SQL

Добавлено: 13 сен 2010, 19:30
Alex_R
Спасибо огромное! Но осталось еще пара неяных моментов:
1) как обойти это ограничение "При использовании GROUP BY в предложении SELECT могут быть указаны только те столбцы, которые поименованы в предложении GROUP BY, и любые агрегатные функции."
2)зачем надо COALESCE(KatPodr.Name, '''') и зачем Left перед Join.

Re: Прямой SQL

Добавлено: 14 сен 2010, 09:08
ilshat
Alex_R писал(а):Спасибо огромное! Но осталось еще пара неяных моментов:
1) как обойти это ограничение "При использовании GROUP BY в предложении SELECT могут быть указаны только те столбцы, которые поименованы в предложении GROUP BY, и любые агрегатные функции."
2)зачем надо COALESCE(KatPodr.Name, '''') и зачем Left перед Join.
Вот эти все вопросы уже касаются совсем не Галактики, а конкретного движка БД на котором у вас база. Вы даже не написали что за БД.
1. Ограничение на group by оно базовое со времен "царя гороха"... на mssql (начиная с 2005) можно его "обойти" конструкцией over (partition by ...)
2. COALESCE это чтобы вместо NULL пустую строку вернуло (находится ответ любым поисковиком за n секунд)... Left перед Join говорит что это левый джойн... объяснять такие основы не буду... читайте книги

Re: Прямой SQL

Добавлено: 14 сен 2010, 19:00
Alex_R
ilshat писал(а): Вот эти все вопросы уже касаются совсем не Галактики, а конкретного движка БД на котором у вас база. Вы даже не написали что за БД.
1. Ограничение на group by оно базовое со времен "царя гороха"... на mssql (начиная с 2005) можно его "обойти" конструкцией over (partition by ...)
2. COALESCE это чтобы вместо NULL пустую строку вернуло (находится ответ любым поисковиком за n секунд)... Left перед Join говорит что это левый джойн... объяснять такие основы не буду... читайте книги
[/quote]

Спасибо за наводку на over (partition by ...).
База Oracle 10. Насколько смог понять из vipprogr.chm запрос все равно преобразуется в такой который должен быть понятен всеми СУБД с которыми работает Галактика (если я понял не правильно буду рад пояснениям).
Вопросы касающиеся основ задаю потому, что по образованию я экономист, с необходимостью писать SQL запросы столкнулся месяца 4 назад(учился их писать по vipprogr.chm), а с необходимосью использования DSQL столкнулся пару недель назад. Книги читаю, но как показывает моя практика в ответах на простые вопросы тоже можно найти то чего нет в книгах.
Еще раз спасибо за ответы.

Re: Прямой SQL

Добавлено: 14 сен 2010, 21:34
Vik
Если вам приходилось описывать вьюхи в випе, или писать запросы в саппорте, то Left Join даст тот же эффект, что и мягкая подцепка ( == ), а просто Join будет соответствовать жесткой подцепке ( /== ).

Re: Прямой SQL

Добавлено: 15 сен 2010, 12:19
BlazeBio
Кто-нибудь может привести примерчик по вызову процедуры средствами DSQL? :grin:

Re: Прямой SQL

Добавлено: 15 сен 2010, 13:00
Vik

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

      .appendSQL(',(CASE KatMarsh.ParGroup')
      .appendSQL('    WHEN')
      .appendSQL('      #COMP(0) THEN 0')
      .appendSQL('    ELSE')
      .appendSQL('      COALESCE')
      .appendSQL('      (')
      .appendSQL('     	  GETPAROPER')
      .appendSQL('          (')
      .appendSQL('      		   ' + coMarsh_Sp)
      .appendSQL('        		,Marsh_Sp.Nrec')
      .appendSQL('        		,' + coMnfOper)
      .appendSQL('        		,Marsh_Sp.Nope')
      .appendSQL('        		,p2.Block, p2.Ind')
      .appendSQL('        		,p1.Block, p1.Ind')
      .appendSQL('          ) ')
      .appendSQL('        ,0')
      .appendSQL('       ) / 6000')
      .appendSQL('      + RsvOPer.Kol *')
      .appendSQL('      COALESCE')
      .appendSQL('      (')
      .appendSQL('     	  GETPAROPER')
      .appendSQL('          (')
      .appendSQL('      		   ' + coMarsh_Sp)
      .appendSQL('        		,Marsh_Sp.Nrec')
      .appendSQL('        		,' + coMnfOper)
      .appendSQL('        		,Marsh_Sp.Nope')
      .appendSQL('        		,p3.Block, p3.Ind')
      .appendSQL('        		,p1.Block, p1.Ind')
      .appendSQL('          ) ')
      .appendSQL('        ,0')
      .appendSQL('       ) / 6000')
      .appendSQL('   END')
      .appendSQL(' ) AS CapacityPlan')
      .appendSQL(',ROUND(INT64(RsvOper.cRoleAn3)/6000,2) AS CapacityFact')


Re: Прямой SQL

Добавлено: 15 сен 2010, 13:14
BlazeBio
.appendSQL что это? Я в доке не нашёл.

Re: Прямой SQL

Добавлено: 15 сен 2010, 13:17
Vik
Эмм.. Из кода своего взял не глядя. Не обращайте на это внимания. Считайте, что это sqlAddStr.

Re: Прямой SQL

Добавлено: 15 сен 2010, 13:45
BlazeBio
А так можно сделать?

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

interface isqltable 'DSQL';
table struct plans
(
  nrec:comp,
  name: string,
  mckod: string,
  ed:string,
  podr:string,
  m_plan:longInt,
  mb_plan:longInt,
  mf_plan:longint,
  diff:longInt
)
with index
(
  plan01 = nrec (unique, surrogate),
  plan02 = name,
  plan03 = mckod,
  plan04 = ed,
  plan05 = podr,
  plan06 = m_plan,
  plan07 = mb_plan,
  plan08 = mf_plan,
  plan09 = diff
);

create view
var tek_date:date;
as select
  *
from
plans
;


screen sPlan;
  show at(,1,,10);
fields
	tek_date;
buttons
	cmReport ,,,'Плановый отчёт',,;
<<
Введите дату: .@@@@@@@@@@

 <.Сформировать отчёт.>

>>
end;
browse bPlan;
  show at(,11,,);
  table plans;

fields
  name    'Мц' : [15], protect, noDel;
  mckod   'код МЦ' : [5], protect, noDel;
  ed 	  'Единицы изм.':[3],protect,noDel;
  podr	  'Подразделение':[15],protect,noDel;
  m_plan  'Месячный план':[5],protect,noDel;
  mb_plan 'План на тек.дату':[5],protect,noDel;
  mf_plan 'Факт на тек.дату':[5],protect,noDel;
  diff    'Разность факта и плана':[5],protect,noDel;
end;

//-------------------------------------------------------------
handleEvent
cmInit:
{
  var stmt : longInt;
  var code : word;
  var str  : string;
  var n    : longInt;
  var stmt_str : LongInt;


  BeginTransaction(0);
  stmt := SqlAllocStmt;
  SqlBindParam(stmt, 1, tek_date);
  SqlExecStmt(stmt, 'COMPARE_REPORT_GROUPMC(?)');
  Message('Код sqlExecStmt: ' + string(sqlErrorCode(stmt)));
  SqlFreeStmt(stmt);
  EndTransaction;

  BeginTransaction(0);
  stmt := sqlAllocStmt;
  sqlExecStmt(stmt, 'SELECT name, mckod, ed,ware, month_plan, plan_from_month_begin, fact_from_month_begin, difference from biblises.pp_tmp_table');
  Message('Код sqlExecStmt: ' + string(sqlErrorCode(stmt)));
  sqlFetchInto(stmt, tnplans);
  sqlFreeStmt(stmt);
    EndTransaction;
/*	_loop plans
	{
		message(plans.name);
	}*/
}
end; // handleEvent

end.
Я не знаю правильно ли(компиляция проходит нормально), в процедуре параметры RepDate in date, RepCur out ReportsCur(курсорный тип - не знаю как его обработать), а таблицы в Галактике у нас находятся в схеме gal810. Необходимо брать данные из biblises.pp_tmp_table и вставлять в plans. В итоге в plans ничего нет - таблица пуста. Что делать? :(

Re: Прямой SQL

Добавлено: 15 сен 2010, 14:33
Vik
Так сложно чего-то сказать, мало что понятно. Только у меня возник вопрос, а вы уверены, что вам тут DSQL нужен? По-моему и без него можно обойтись. Тем более, если процедура возвращает курсор. Нет в vip-е такого типа)

Re: Прямой SQL

Добавлено: 15 сен 2010, 14:39
BlazeBio
Vik писал(а):Так сложно чего-то сказать, мало что понятно. Только у меня возник вопрос, а вы уверены, что вам тут DSQL нужен? По-моему и без него можно обойтись.
Нет, не уверен. Процедура и таблица написаны не мной в Oracle, а требуется получить данные из таблицы biblises.pp_tmp_table(временная - нужна для отработки процедуры) и использовать их в ard-отчёте. Буду рад любому способу решения проблемы :)

Re: Прямой SQL

Добавлено: 15 сен 2010, 15:38
Vik
Решение проблемы: взять и написать нужный отчет на випе без всяких DSQL :)