Помогите научиться работать с SQL из Клариона
Добавлено: 23 Январь 2007, 19:06
Задача следующая:
есть Access-ная база (MDB), в ней таблицы.
требуется выполнять несложные запросы (SELECT,UPDATE,INSERT) к этим таблицам.
словарь делать не нужно.
Начал решать -- посмотрел на пример работы с ADO (рукописный код) с сайта clarionlife.net -- понравилось (очень уж все просто -- запрос в виде строки, а результат - в очередь).
Написал программку, она работает.
Но! Столкнулся с проблемами:
1.Строка запроса ограничена приблизительно 2мя килобайтами (2-3 кБ)
2.Результат тоже видимо ограничен (получаю аналогичное сообщение - что-то о слишком длинном поле)
И самое главное!!!
3.Жрет память. Когда запросов немного -- не заметно, когда начинаю в цикле выполнять несколько сотен запросов, то память отжирается (судя по диспетчеру задач) десятками и сотнями мегабайт. В конце-концов программе просто не хватает ресурсов и она умирает.
Отсюда вывод -- что-то я делаю не так.
Понять бы как делать "так"?
Поделитесь опытом, плз, как выполнять произвольный запрос, не привязываясь к словарям?
Привожу кусок кода, которым я пользуюсь:
строка коннекта к базе:
запрос:
есть Access-ная база (MDB), в ней таблицы.
требуется выполнять несложные запросы (SELECT,UPDATE,INSERT) к этим таблицам.
словарь делать не нужно.
Начал решать -- посмотрел на пример работы с ADO (рукописный код) с сайта clarionlife.net -- понравилось (очень уж все просто -- запрос в виде строки, а результат - в очередь).
Написал программку, она работает.

Но! Столкнулся с проблемами:
1.Строка запроса ограничена приблизительно 2мя килобайтами (2-3 кБ)
2.Результат тоже видимо ограничен (получаю аналогичное сообщение - что-то о слишком длинном поле)
И самое главное!!!
3.Жрет память. Когда запросов немного -- не заметно, когда начинаю в цикле выполнять несколько сотен запросов, то память отжирается (судя по диспетчеру задач) десятками и сотнями мегабайт. В конце-концов программе просто не хватает ресурсов и она умирает.
Отсюда вывод -- что-то я делаю не так.
Понять бы как делать "так"?
Поделитесь опытом, плз, как выполнять произвольный запрос, не привязываясь к словарям?
Привожу кусок кода, которым я пользуюсь:
строка коннекта к базе:
Код: Выделить всё
GLO:Conn&=sqlConnect('Provider=Microsoft.Jet.OLEDB.4.0;Data Source='&clip(loc:DBName)&';Jet OLEDB:Database Password=111111;',Err#)
Код: Выделить всё
sqlExecute(GLO:Conn,'INSERT INTO Firm ('&|
'[Name],'&|
'[Index],'&|
'[Country],'&|
'[Town],'&|
'[Region],'&|
'[Street],'&|
'[House],'&|
'[Korp],'&|
......................
'[Deleted]'&|
') VALUES ('&|
''''&clip(QP:Name)&''','&|
''''&clip(QP:Index)&''','&|
''''&clip(QP:idCountry)&''','&|
''''&clip(QP:idTown)&''','&|
''''&clip(QP:idRegion)&''','&|
''''&clip(QP:idStreet)&''','&|
''''&clip(QP:House)&''','&|
''''&clip(QP:Korp)&''','&|
..........................
''''&(0)&''''&|
');')
Код: Выделить всё
sqlExecute PROCEDURE (pConn,sqlQuery,<queryQ>,<FlagPosition>) ! Declare Procedure
pRecordSet &CRecordSet
pCommand &CCommand
pFields &CFields
pField &CField
cstrCommandText CSTRING(5120)
bEof SHORT
dwCount LONG
bstrName BSTRING
gVar LIKE(gVariant)
aVar VARIANT,OVER(gVar)
posCounter LONG
CurrentQueueField ANY
CurrentQueueFieldName STRING(64)
CODE
if ~omitted(3)
free(queryQ)
end
if (GLO:xPCListConn&=NULL) then return.
pRecordSet &= new(CRecordSet)
Err#=pRecordSet.Init()
Err#=pRecordSet.PutCursorLocation(adUseClient)
pFields &= new(CFields)
pField &= new(CField)
pCommand &= new(CCommand)
if ~(pCommand &=NULL)
Err#=pCommand.Init()
Err#=pCommand.PutRefActiveConnection(pConn)
Err#=pCommand.PutCommandType(adCmdText)
cstrCommandText=clip(sqlQuery)
Err#=pCommand.PutCommandText(cstrCommandText)
pRecordSet&=pCommand._Execute(,Err#)
if ~Err# ! если все без ошибок
if ~omitted(3)
if NOT pRecordSet.GetEof(bEof) then
if bEof<>-1 then
do ProcessFields
loop
if pRecordSet.MoveNext() then break.
if pRecordSet.GetEof(bEof) then break.
if bEof=-1 then break.
do ProcessFields
end
end
end
end
end
end
!!!AnDS -- этого кода в примере не было, думал поможет память освободить -- не помогло :-(
dispose(pField)
dispose(pFields)
pRecordSet.Destruct()
!!!AnDS
ProcessFields routine
pFields &= pRecordSet.GetFields(Err#)
Err# = pFields.GetCount(dwCount)
loop i#=0 to dwCount-1
pField &= pFields.GetField(i#, Err#)
Err#=pField.GetName(bstrName)
Err#=pField.GetValue(gVar)
case FlagPosition
of sql:ByName
posCounter=0
loop
posCounter+=1
CurrentQueueFieldName=WHO(queryQ,posCounter)
if clip(CurrentQueueFieldName)='' then break.
if UPPER(clip(CurrentQueueFieldName))=UPPER(clip(bstrName))
CurrentQueueField&=WHAT(queryQ,posCounter)
if ~(CurrentQueueField&=NULL)
CurrentQueueField=aVar
end
end
end
of sql:ByPos
CurrentQueueField&=WHAT(queryQ,i#+1)
if ~(CurrentQueueField&=NULL)
CurrentQueueField=aVar
end
end
end
if (dwCount) then add(queryQ). ! пропустим если пусто