Прямой SQL
Модераторы: m0p3e, edward_K, Модераторы
-
- Местный житель
- Сообщения: 1844
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Ярославская область ОАО "Часовой завод Чайка" г. Углич
- Контактная информация:
Re: Прямой SQL
если Вы про FCOM то там доступны модификаторы только в рамках логической таблицы
Re: Прямой SQL
Так дело в том, что один апдейт сработал на таблицу basedoc, а на таблицу spstep апдейт не проходит.Den писал(а):если Вы про FCOM то там доступны модификаторы только в рамках логической таблицы
Re: Прямой SQL
Подскажите, пожалуйста, как передать результаты выборки прямого sql в поток Fastreport?
Re: Прямой SQL
Yurii38
В FR доступен компонент ADOQuery, где можно написать запрос. Если сильно хочется использовать DSQL, то, думаю, через таблицу в памяти.
В FR доступен компонент ADOQuery, где можно написать запрос. Если сильно хочется использовать DSQL, то, думаю, через таблицу в памяти.
Re: Прямой SQL
Yurii38 писал(а):Подскажите, пожалуйста, как передать результаты выборки прямого sql в поток Fastreport?
Код: Выделить всё
/*
Пример использования объектного интерфейса для доступа к прямому SQL и связки
его с потоком данных FastReport
*/
#include Query.vih
Interface FrIQueryDemoReport;
create view;
sql query sqlQuery1 =
SELECT
sum(o.SumOb) Summa, sum(o.Kol) Kolvo, o.SchetO Debit, O.DatOb DatOb
FROM Oborot O
WHERE
O.DatOb >= :dBegin
and O.DatOb <= :dEnd
GROUP BY O.DatOb, o.SchetO
ORDER BY O.DatOb, o.SchetO;
var CurrentQuery : IQuery;
var ExecuteErrorCode : integer
var FetchErrorCode : integer;
function CurrentQuerySafeGetValue(AField : string) : variant;
{
if( not NullVipRef(CurrentQuery) and (ExecuteErrorCode = tsOk) )
result := CurrentQuery.row.col(AField).value
else
result := '';
}
datastream SubTotalStream
(
// реквизиты организации для заголовка и подножия отчета
[ExecuteErrorCode] ExecuteErrorCode;
[FetchErrorCode] FetchErrorCode;
// элемент потока данных управляемый программно
dataset IQueryDataSet
(
[Summa] CurrentQuerySafeGetValue('Summa');
[Kolvo] CurrentQuerySafeGetValue('Kolvo');
[Debit] CurrentQuerySafeGetValue('Debit');
[DatOb] LongToDate(CurrentQuerySafeGetValue('DatOb'));
);
)
handleEvent dataset IQueryDataSet
cmPreProcess:
{
// Инициализация запроса Direct-SQL
CurrentQuery := queryManager.createQuery(sqlQuery1);
CurrentQuery.SetParam('dBegin', date(1,2,2010));
CurrentQuery.SetParam('dEnd', date(28,2,2010));
ExecuteErrorCode := CurrentQuery.Execute.ErrorCode;
}
cmOnProcess:
{
if(CurrentQuery.Fetch.ErrorCode = tsOk)
ContinueDataset;
}
cmPostProcess:
{
// Де инициализация объекта запроса
CurrentQuery := NullRef;
}
end;
end;
handleEvent
cmInit:
{
RunFReport(SubTotalStream, '', false);
Abort;
}
end;
end.
-
- Местный житель
- Сообщения: 552
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Челябинск
- Контактная информация:
Re: Прямой SQL
Всем доброго!
Возникла проблема в применении вложенного цикла в dsql. Вот кусок внешнего цикла, где S$BD_KS_MNPLAN- хранимая процедура, mt- хендл временной таблицы
Внешний цикл отрабатывает нормально, а во внутреннем, реализованном функцией sBdMc, происходит падение:
Имею лог драйвера:
01.03.2014 10:55:28 [NAZ]:
{CALL GetProcName(?,?,?)}
01.03.2014 10:55:28 [NAZ]:
HY000: [Microsoft][ODBC SQL Server Driver]Подключение занято до получения результатов для другого hstmt
01.03.2014 10:55:28 [NAZ]:
{CALL FT000000000000000000000000000S(? )}
01.03.2014 10:55:28 [NAZ]:
HY000: [Microsoft][ODBC SQL Server Driver]Подключение занято до получения результатов для другого hstmt
...
Как будто внутренний цикл конфликтует с внешним, хотя используются разные обозначения хендлов. Что не так??
Возникла проблема в применении вложенного цикла в dsql. Вот кусок внешнего цикла, где S$BD_KS_MNPLAN- хранимая процедура, mt- хендл временной таблицы
Код: Выделить всё
...
stmt := sqlAllocStmt;
if sqlExecStmt(stmt, 'BD_KS_MNPLAN') = tsOk
{
if sqlFetchIntomt(stmt, mt) = tsOk
{
if sqlNavigateMT(mt, ffGetFirst, rec) = tsOk then
{
do
{
...
smemo:= sBdMc(nMnPlan, comp(rec[4]));
}
while sqlNavigateMT(mt, ffGetNext, rec) = tsOk;
} else message('sqlNavigateMT <> tsOk!')
} else message('sqlFetchIntomt <> tsOk!')
} else message('sqlExecStmt(stmt, BD_KS_MNPLAN) <> tsOk!')
SqlFreeStmt(stmt);
SqlFreeMt(mt);
Код: Выделить всё
function sBdMc(cMn: comp; cMcU: comp): string; //Получить строку со списком ДО
{
var stmtf, strHandlef: longint; var _sBdMc, sBdn, sBdd: string;
stmtf := sqlAllocStmt;
SqlBindParam(stmtf, 1, cMn); SqlBindParam(stmtf, 2, cMcU);
sqlBindCol( stmtf, 1, sBdn); sqlBindCol( stmtf, 2, sBdd);
SQLAddStr(strHandlef, 'select top 100 basedoc.nodoc, IntDateToString(basedoc.ddoc) from basedoc inner join objacct on basedoc.nrec = objacct.cowner inner join');
SQLAddStr(strHandlef, ' mnplan on objacct.cobject = mnplan.nrec inner join stepdoc on basedoc.nrec = stepdoc.cbasedoc inner join');
SQLAddStr(strHandlef, ' spstep on stepdoc.nrec = spstep.cstepdoc inner join spmnplan on mnplan.nrec = spmnplan.cmnplan and spstep.cmcusl = spmnplan.cizd');
SQLAddStr(strHandlef, ' where objacct.typeobj = 17 and objacct.typeown = 34 and basedoc.viddoc = 101 and mnplan.nrec = ? and spmnplan.cizd = ?');
SQLAddStr(strHandlef, ' order by basedoc.ddoc');
sqlPrepare(stmtf, strHandlef); // Здесь падение!
sqlExecute(stmtf);
...
sqlFreeStr(strHandlef);
SqlFreeStmt(stmtf);
if _sBdMc <> '' then sBdMc:= _sBdMc; else sBdMc:= ''
}
01.03.2014 10:55:28 [NAZ]:
{CALL GetProcName(?,?,?)}
01.03.2014 10:55:28 [NAZ]:
HY000: [Microsoft][ODBC SQL Server Driver]Подключение занято до получения результатов для другого hstmt
01.03.2014 10:55:28 [NAZ]:
{CALL FT000000000000000000000000000S(? )}
01.03.2014 10:55:28 [NAZ]:
HY000: [Microsoft][ODBC SQL Server Driver]Подключение занято до получения результатов для другого hstmt
...
Как будто внутренний цикл конфликтует с внешним, хотя используются разные обозначения хендлов. Что не так??
-
- Заслуженный деятель интернет-сообщества
- Сообщения: 5188
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: SPB galaxy spb
Re: Прямой SQL
Где то в доке было написано про это - что нельзя использовать одновременно 2 DSQL.
Выход один - Выгружать 1 DSQL во временную таблицу, а второй можно оставить и так.
Как то так
Либо вообще объедините запросы в один - будет на порядок шустрее.
Выход один - Выгружать 1 DSQL во временную таблицу, а второй можно оставить и так.
Как то так
Код: Выделить всё
IdTable :=#table // число полей и тип во временной таблице должен строго совпадать с запросом
vliErrorCode := sqlPrepare(stmt, vliSQLCommand);
if (vliErrorCode = 0)
{
vliErrorCode := sqlExecute(stmt);
LogSql( 'Выполнение SQL запроса Execute>Таблица >> Стоп : ' + string(vliErrorCode));
vliErrorCode := FitchExec(IdTable);
LogSql( ' FitchExec= : ' + string(vliErrorCode));
ClearQuery(vliSQLCommand);
}
else
LogSql( 'Подготовка SQL запроса >> ошибка №' + string(vliErrorCode));
sqlFreeStmt(stmt);
ClearQuery(vliSQLCommand);
-
- Местный житель
- Сообщения: 552
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Челябинск
- Контактная информация:
Re: Прямой SQL
Понятно. Жаль, конечно..лишние заморочки. Спасибо за ответ!
-
- Заслуженный деятель интернет-сообщества
- Сообщения: 5188
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: SPB galaxy spb
Re: Прямой SQL
ЗЫ. Я вообще отказался от sqlBindCol и SqlBindParam - условия генерю сразу в код запроса а выгружаю во временку - тогда sqlBindCol не нужен как и Fetch .
Re: Прямой SQL
Такой вопрос, делаю через прямой sql временную таблицу и заполняю ее данными запроса. Во view читаю эту временную таблицу и заполняю другую времянку. Далее эти данные передаю в excel-файл. Запрос работает, выводит данные. По итогу excel-файл пустой...
Код: Выделить всё
.FORM 'Ведомость наличия норм страхового запаса'
.ard
.var
day1,month1,year1:integer;
day2,month2,year2:integer;
BegDate,EndDate:date;
stmt, astmt : longint;
.endvar
.begin
RunDIALOG('C_COMMON::GETINTERVAL',BegDate, EndDate);
day1:=day(BegDate);
month1:=month(BegDate);
year1:=Year(BegDate);
day2:=day(EndDate);
month2:=month(EndDate);
year2:=Year(EndDate);
end.
.var
T_kmc:longint;
T_mc, T_podr:string;
T_kol_ost, T_kol_norm:double;
sch , x , xlsi, ks : integer ;
.endvar
table struct tnormost
(
mcname : string,
podrname : string,
kolost : double,
kolnorm : double
)
with index (n = mcname);
.create view t1
as SELECT *
from tnormost;
.begin
stmt := sqlAllocStmt;
//Создаем ВТ
sqlDropTmpTable('tnormost');
! Message('должна удалиться',0)
! sqlDropTmpTable(UpCase ( UserName ) +'.MyData');
! Message('а теперь?',0)
sqlCreateTmpTable('Table tnormost (mcname : string, podrname : string, kolost : double, kolnorm : double);', ctmNormal);
//Заполняем ВТ
! sqlExecStmt(stmt,'select basedoc.nrec, basedoc.ddoc, basedoc.nodoc from basedoc inner join ttndoc on (BaseDoc.Nrec = TTNDOC.CDOC) and ttndoc.wtable=1102 inner join attrval on ttndoc.nrec = attrval.CREC inner join attrnam on attrval.cattrnam = attrnam.nrec and attrnam.nrec = comp(''281474976711117'')');
! sqlExecStmt(stmt,'SELECT t1.name, katpodr.name, t1.kol, t1.normkol from( select s.cmc,mc.name, s.cmol,s.cparty,s.cpodr,s.kolp,s.kolr,s.kol,nzs.kol as normkol, s.srprice,s.dsaldo, max(s.dsaldo) OVER(partition by s.cmc, s.cmol, s.cparty, s.cpodr) as maxdate from katmc mc, NORMZAPAS nz, NORMZAPASSPEC nzs, saldomc s inner join katpodr podr on s.cpodr=podr.nrec where s.dsaldo<=#date(31,12,2100) and NZ.ATL_NREC = NZS.CNORM and NZS.CMC = s.cmc and s.CPODR = NZ.CPODRAZD and s.cmc = mc.nrec and s.cpodr <> (''0000000000000000h'')) t1 inner join katpodr on t1.cpodr=katpodr.nrec left join katmol mol on t1.cmol=mol.nrec left join katparty party on t1.cparty=party.nrec where dsaldo = maxdate and (t1.kolp-t1.kolr)<>0;');
sqlExecStmt(stmt,'sql SELECT mc.name mcname, katpodr.name podrname, t1.kol kolost, nzs.kol kolnorm from( select s.cmc, s.cmol,s.cparty,s.cpodr,s.kolp,s.kolr,s.kol, s.srprice,s.dsaldo, max(s.dsaldo) OVER(partition by s.cmc, s.cmol, s.cparty, s.cpodr) as maxdate from saldomc s where s.dsaldo<=#date(31,12,2100) and s.cpodr <> (''0000000000000000h'')) t1 right join NORMZAPASSPEC nzs on t1.cmc = NZS.CMC inner join katmc mc on nzs.cmc = mc.nrec inner join NORMZAPAS nz on NZS.CNORM = NZ.ATL_NREC inner join katpodr on nz.cpodrazd=katpodr.nrec where dsaldo = maxdate and (t1.kolp-t1.kolr)<>0');
//Читаем ВТ
! sqlExecStmt(stmt,'select F from MyData');
sqlFetchInto(stmt, tntnormost);
sqlFreeStmt(stmt);
end.
.begin
T_kmc:=Tblinitnew(12,1);
T_mc:=Tblnewfield(T_kmc,12);
T_podr:=Tblnewfield(T_kmc,12);
Tblendkey(t_Kmc);
T_kol_ost:=Tblnewfield(T_kmc,12);
T_kol_norm:=Tblnewfield(T_kmc,12);
TblSetDuplicate(T_kmc,true);
TblClearbuffer(T_kmc);
end.
.{table 't1'
.begin
TblClearBuffer(T_kmc);
TblSfString(T_kmc,T_mc, t1.tnormost.mcname)
TblSfString(T_kmc,T_podr, t1.tnormost.podrname)
If(TblGetEqual(T_kmc))
{
TblSfDouble(T_kmc,T_kol_ost,TblgfDouble(T_kmc,T_kol_ost) + t1.tnormost.kolost)
TblSfDouble(T_kmc,T_kol_norm,TblgfDouble(T_kmc,T_kol_norm) + t1.tnormost.kolnorm)
TblUpdateCurrent(T_kmc);
}
else
{
TblSfDouble(T_kmc,T_kol_ost, t1.tnormost.kolost)
TblSfDouble(T_kmc,T_kol_norm, t1.tnormost.kolnorm)
TblInsertCurrent(T_kmc);
}
end.
.}
.begin
xlCreateExcel('Ведомость наличия норм страхового запаса' , true);
if (xlIsExcelValid)
xlSetActiveWorkBookByName('Ведомость наличия норм страхового запаса');
xlSetSheetName(1, '');
xlSetActiveSheet(1);
X:=0;
xlsi := 3;
ks := 4;
SCH:=TBLRECORDS(T_kmc)-1;
xlSetCellStringValue('Ведомость наличия норм страхового запаса',1,1,1,1);
xlSetCellStringValue('с '+BegDate+' по '+EndDate,2,1,2,1);
XLCREATEMATRIX(sch+xlsi, ks);
xlClearMatrix;
xlStWriteToMatrix(1, 1, 'Наименование МЦ');
xlSetColumnWidth(25,1,1,sch,1)
xlStWriteToMatrix(1, 2, 'Количество по остаткам');
xlSetColumnWidth(14,1,2,sch,2)
!xlWrapText(4,1,sch,ks)
xlStWriteToMatrix(1, 3, 'Количество по нормам');
xlSetColumnWidth(10,1,3,sch,3)
xlsi := 3;
end.
.{WHILE X<=SCH
.BEGIN
xlsi := xlsi + 1
IF TBLGETINDEX(T_kmc,X)
{ }
X:=X+1
xlStWriteToMatrix(xlsi, 1, Substr(TblGfString(T_kmc,T_mc),1,50))
xlStWriteToMatrix(xlsi, 2, TblgfString(T_kmc,T_kol_ost))
xlStWriteToMatrix(xlsi, 3, TblgfDouble(T_kmc,T_kol_norm))
! if Round(TBLGFdouble(T_kmc,T_kol),0)<> 0
! { xlDoWriteToMatrix(xlsi, 5, TBLGFdouble(T_kmc,T_kol)) }
! else
! { xlStWriteToMatrix(xlsi, 5, '') } ;
end.
.}
.begin
XLWriteMatrixToExcel(4,1);
xlImportModule('\\SRV31\810_res\06\uchet.bas')
!xlImportModule('d:\program\uchet.bas')
xlRunMacro('rez.rez');
xlKillExcel;
END.
!logstrtofile('d:\name.txt', t1.katmc.name, t1.spsopr.kolfact, t1.)
.endform
-
- Местный житель
- Сообщения: 589
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Воронеж ОАО Верофарм. Воронеж
Re: Прямой SQL
Доброго времени суток.
В продолжение темы.
Пробую интерфейс с прямым скулем.
Текст запроса:
Выдает ошибку (Ora73drv)
Причем, если запрос выполнить в суппорте или в Toad (изменив в этом случае имена полей - подставив префикс f ), все работает, данные получаю верные.
В чем ошибка? (Пытался выполнять без имени схемы - ошибок нет, данных нет, пытался ставить поля с префиксом f - та же ошибка)
Oracle-8. Галактика 8.10
В продолжение темы.
Пробую интерфейс с прямым скулем.
Текст запроса:
Код: Выделить всё
stmt := sqlAllocStmt;
sqlAddStr(StmtString,'select t1.dSopr, t1.name, Sum(sale), Sum(sebest), t1.cpodrfrom from ');
sqlAddStr(StmtString,'(select KatSopr.dSopr, KatSopr.VhodNal, Katmc.name, Sporder.kol*Sporder.srprice ');
sqlAddStr(StmtString,' sebest, Spsopr.price*Sporder.kol sale, KatSopr.cPodrFrom from vrn.KatSopr, vrn.Katmc, vrn.Sporder, vrn.Spsopr where ');
sqlAddStr(StmtString,' KatSopr.VidSopr=201 and KatSopr.dSopr >= '+GetDateAsPascalLongint(dtBegdate)+' and KatSopr.dSopr <= '+GetDateAsPascalLongint(dtFindate)+' and ');
sqlAddStr(StmtString,' KatSopr.nRec = Spsopr.cSopr and ');
sqlAddStr(StmtString,' Spsopr.nrec=Sporder.cspsopr and Sporder.vidorder=1 and Spsopr.cmcusl = Katmc.fnrec ) t1 group by t1.dsopr, t1.name, t1.cpodrfrom');
Message(sqlPrepare ( stmt, StmtString ),0);
Message(sqlExecute ( stmt ),0);
sqlFetchInto(stmt, tntblsalesNota);
Message('err='+string(sqlErrorCode(stmt)),0);
sqlFreeStmt(stmt);
Код: Выделить всё
select t1.dSopr, t1.name, Sum(sale), Sum(sebest), t1.cpodrfrom from
(select KatSopr.dSopr, KatSopr.VhodNal, Katmc.name, Sporder.kol*Sporder.srprice
sebest, Spsopr.price*Sporder.kol sale, KatSopr.cPodrFrom from vrn.KatSopr, vrn.Katmc, vrn.Sporder, vrn.Spsopr where
KatSopr.VidSopr=201 and KatSopr.dSopr >= 132055297 and KatSopr.dSopr <= 132055562 and
KatSopr.nRec = Spsopr.cSopr and
Spsopr.nrec=Sporder.cspsopr and Sporder.vidorder=1 and Spsopr.cmcusl = Katmc.fnrec ) t1 group by t1.dsopr, t1.name, t1.cpodrfrom
10.02.2015 13:11:31 [SAVINKOV]:
Ошибка(2,21): Таблица или представление не определено KATSOPR
В чем ошибка? (Пытался выполнять без имени схемы - ошибок нет, данных нет, пытался ставить поля с префиксом f - та же ошибка)
Oracle-8. Галактика 8.10
-
- Местный житель
- Сообщения: 589
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Воронеж ОАО Верофарм. Воронеж
Re: Прямой SQL
Вопрос снят!
-
- Местный житель
- Сообщения: 589
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Воронеж ОАО Верофарм. Воронеж
Re: Прямой SQL
Еще раз к вопросу прямого sql в ard отчетах.
Сделал в проекте временную таблицу. DSQL запросом выгрузил в нее данные. А вот еще раз обработать эту таблицу другим прямым скулем не могу. Пишет, что нет такой таблицы.
В view таблица описана. В чем может быть засада? Или все-таки ард с прямым скулем не дружит?
Сделал в проекте временную таблицу. DSQL запросом выгрузил в нее данные. А вот еще раз обработать эту таблицу другим прямым скулем не могу. Пишет, что нет такой таблицы.
В view таблица описана. В чем может быть засада? Или все-таки ард с прямым скулем не дружит?
-
- Местный житель
- Сообщения: 1844
- Зарегистрирован: 29 мар 2005, 17:49
- Откуда: Ярославская область ОАО "Часовой завод Чайка" г. Углич
- Контактная информация:
Re: Прямой SQL
если Вы к ней хотите обратиться в запросе dsql, то ее нужно объявить как временную таблицу dsql (sqlCreateTmpTable)savov писал(а):А вот еще раз обработать эту таблицу другим прямым скулем не могу
Хотя в ard это все будет как ходьба по минному полю. Но попробовать можно.
Re: Прямой SQL
Не знаю, почему у народа такое предубеждение к ard с DSQL: у меня куча таких отчётов, никаких особых проблем не вижу.Den писал(а):Хотя в ard это все будет как ходьба по минному полю.