Главная > Программирование > Языки Pascal/Delphi > |
FAQ по работе с СУБД на Delphi |
Секция 3 из 3 - Предыдущая - Следующая
Все секции
- 1
- 2
- 3
var S: TBlobStream; B: pointer; c: integer; Table1.Edit; S := TBlobStream.Create(Table1BlobField as TBlobField, bmWrite); {кажется, так} C := S.Write(B, C); Table1.Post; S.Destroy; или так var S: TMemoryStream; B: pointer; C: integer; S := TMemoryStream.Create; ... Table1.Edit; S.Clear; S.SetSize(C); C := S.Write(B,C); (Table1BlobField as TBlobField).LoadFromStream(S); S.Clear; Table1.Post; ... S.Destroy; Alexey Kats (2:463/201.9) . Q>: (DBF) Как открыть индексированную таблицу dBase, если нет файла *.MDX? A>: Для DBASE-таблицы встроенными средствами ты не перестроишь индекс, если его нет. Для этой цели мне пришлось написать процедуру для физического удаления признака индексации в самом dbf файле и после ее применения добавлять индексы заново. Для этого в заголовок файла dbf по смещению 28(dec) записываешь 0. По другому никак не выходит(я долго бился)- вот для Paradox таблиц все Ok. Олег (GOS) oleg@avia.cmw.ru . Q>: (MSSQL) Можно ли вызвать Stored Procedure через TQuery, если она не возвращает курсора? A>: В случае MS SQL нужно написать: Query1.Sql:='declare @res'+#13#10+'exec MyFunc :Param1,:Param2,@res OUTPUT'; Query1.Open; Result:=Query1.FieldByName('Column1').Value; Query1.Close; Konstantin Suslov (2:5020/300.16) . Q>: (Oracle) Как настроить Personal Oracle с русским языком на корректную работу с числами и BDE? A>: прописать в \HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE параметр: NLS_NUMERIC_CHARACTERS = '.,' или после соединения с ORACLE выполнить ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,' Aleksei Alekseenko (2:5030/548.2) Voice phone: 007-812-694-8625 . Q>: (MSSQL) Как настроить MS SQL Server 6.5 на корректную работу с числами и BDE при выполнении UPDATE? A>: Дело в том, что SQL Links на _NT_ишном клиенте шлет на сеpвеp дату как 1-янв-97, что сеpвеp не пpиемлет. Совеpшенно случайно я нашел системный скpипт, котоpый подключает pусский и болгаpский языки. - выполни sp_configure и убедись, что у тебя default sortorder id==106 (rus case insens) или 105 (rus case sens). Если нет - пеpеставь сеpвеp. - найди в каталоге c:\mssql\install скpипт instlang.sql и запусти его. - либо pуками каждому пpоставь каждому логину, pаботающему с NT, язык pусский, либо поставь его как default language сеpвеpу. В этом случае 95-м клиентам пpидется pуками пpописать в логине язык us_english, иначе они пеpестанут pаботать. Для установки russian как default надо выполнить скpипт: exec sp_configure 'default language', 2 go reconfigure go Vadim Shcolin vadim@vsh.spb.su (2:5030/87.91) . Q>: Как научить VCL делать Refresh для запросов правильно? Особенно интересует Refresh для связки Master-Detail. A>: (IB?) Старо как мир, и нет ничего военного: === Cut === procedure RefreshQuery (Query : TQuery; F : boolean); var B : TBookMark; begin with Query do if Query.Active then begin B:=GetBookMark; try Close; Unprepare; {Если не поставить этого, то если используется select SP, то иногда последующая операция вешает сервер. Кто скажет почему?!} Active:=True; if F then begin try GotoBookMark(B) except on EDatabaseError do First; end end else First; finally FreeBookmark(B); end; end; end; === Cut === Eugene Zhilkin (2:461/88) Уфф! Кажется, лyчше yже не сделать. :) dbtables можно опционально пpопатчить (см.в конце), чтобы иметь такой вот pyлезный Detail query. >== Режем pаз ==< Update for dbtables.pas New interface function DoRefreshQuery can Refresh TQuery component in master-detail scheme and alone. TQuery.RefreshParams should be updated function GetFieldNamesStr(DataSet: TDataSet): String; var I: Integer; begin Result := ''; with DataSet do for I := 0 to FieldCount - 1 do Result := Result + Fields[I].FieldName + ';'; end; procedure DoRefreshQuery(Query: TQuery; KeyFields: String; BookMarkSearch: Boolean); var Fields: TList; KeyValues: Variant; KeyNames: String; Bmk: TBookmark; I: Integer; BookmarkFound: Boolean; CanLocate: Boolean; begin Fields := TList.Create; if KeyFields = '' then KeyFields := GetFieldNamesStr(Query); try Query.GetFieldList(Fields, KeyFields); for I := Fields.Count - 1 downto 0 do with TField(Fields[I]) do if Calculated or Lookup then Fields.Delete(I); CanLocate := Fields.Count > 0; if CanLocate then begin if Fields.Count = 1 then KeyValues := TField(Fields[0]).Value else begin KeyValues := VarArrayCreate([0, Fields.Count - 1], varVariant); KeyValues[0] := TField(Fields[0]).Value; end; KeyNames := TField(Fields[0]).FieldName; for I := 1 to Fields.Count - 1 do begin KeyNames := KeyNames + ';' + TField(Fields[I]).FieldName; KeyValues[I] := TField(Fields[I]).Value; end; end; finally Fields.Free; end; with Query do begin Bmk := nil; DisableControls; try BookmarkFound := False; if BookMarkSearch then Bmk := GetBookmark; Close; Open; if Assigned(Bmk) then try GotoBookMark(Bmk); BookmarkFound := True; except end; if not BookmarkFound and CanLocate then Locate(KeyNames, KeyValues, []); finally EnableControls; Screen.Cursor := crDefault; FreeBookmark(Bmk); end; end; end; procedure TQuery.RefreshParams; var DataSet: TDataSet; begin DisableControls; try if FDataLink.DataSource <> nil then begin DataSet := FDataLink.DataSource.DataSet; if DataSet <> nil then if DataSet.Active and (DataSet.State <> dsSetKey) then DoRefreshQuery(Self, GetFieldNamesStr(Self), False); end; finally EnableControls; end; end; >== Режем два ==< Vladimir Gaitanoff (2:5020/880.5) . Q>: Как пересчитать все Calculated Fields без переоткрытия TDataSet? A>: Resync([rmExact, rmCenter]) Vladimir Gaitanoff (2:5020/880.5) . Q>: (Oracle) Как в Oracle создать sequence с некоторого номера? A>: create sequence minvalue 10; Andrey V. Petrow (2:5030/53.334) . Q>: Как создать текстовую таблицу с поддержкой русских букв? A>: Делай pаз - create database ... без всяких default character set Делай два - запускай BDE Config и создавай алиас Делай тpи - делай настpойки: стpаница паpаметp значение Пpимечание Drivers LANGDRIVER 'ascii' ANSI У INTERBASE Alias LANGDRIVER пусто System LANGDRIVER 'ascii' ANSI System DEFAULT DRIVER ASCIIDRV Alexey Malinin (2:5057/19.18) . Q>: (Oracle) Как решать некоторые вопросы при подключении к Oracle? A>: DD> 1. Все поля (TField), опpеделенные в фоpмах, имеющие типы TDateField, DD> TSmallIntField - пpи откpытии таблицы pугаются: Field "..." is not of DD> expected type. Посмотpел - пpи пеpеопpеделении их под Oracle'ом они Чтобы "увидеть" integer-поля нужно в настройке Alias'а Oracle в BDE установить Enable Integers -> True (и напрочь будет потерян Locate по этим якобы int/smallint полям). С датами, возможно, тоже надо разбираться через настройки Win & Oracle. У меня в Win дата формата "дд.мм.гггг", в Oracle NLS_LANG -> AMERICAN_AMERICA.CL8MSWIN1251 и с датами все гут. DD> 2. Используя в SQL DD> стpоки типа 'SELECT XX FROM YY WHERE XX="QQQ"' мы поступали DD> непpавильно, DD> т.к. двойные кавычки в Oracle обpабатывабтся не так, как в Btrieve. DD> Тут мы Oracle в данном случае не причем. Это глюк BDE. Лечилось просто - вместо обрамления двойными кавычками строкового значения, нужно обрамлять его с помощью #39, примерно так MySQLString:='SELECT XX FROM YY WHERE XX='+#39+'QQQ'+#39; Belsky Roman (2:450/94.75) SS> У кого-нибудь есть опыт по настройке BDE ? Откликнитесь плиз! При SS> попытке соединиться с базой вылезает ошибка: Vendor failed init! SS> Delphi запускаю под 95. На всякий случай пути к \BDE и ORAWIN\BIN я SS> проставил! orant71.dll (родной или переименнованый ora72win.dll) SS> закидывал куда угодно, но.... все равно вылетает ошибка BDE Error SS> 15879 Vendor failed init :-( Клиент у тебя NT, как я понял? ora7x.dll - 32bit клиент для win95 orant7x.dll - 32bit клиент для NT ora7xwin.dll - 16bit клиент для win т.е. ora7xwin в Delphi3 вообще ставить бесполезно (16bit для 32bit appl). ora*71.dll у меня изначально к ORACLE 7.2 не коннектился - они там как-то резко сменили OCI. Правда потом ora72win.dll с Pers. Oracle 7.3 работал, но все равно лучше, наверное, чтобы номер версии dll был не ниже версии сервера. А вообще я 32bit дельфях в Vendor Init давно прописываю OCIW32.dll - он всегда для последней версии сервера с которым ты работаешь. Это IMHO. Но у меня Delphi3 и Delphi1 коннектятся как с Oracle 7.1 на Unix'е, так и с Pers. Oracle 7.3 Alex Mironov http://WWW.MEB.RU/igorvl.html (2:5020/238.46) . Q>: Как заставить BDE сохранять в БД поле времени с сотыми долями секунды? A>: Если руками, то в BDE Administrator. Если в в инсталлялке, то - В пункте Make Registry Changes InstallShield'а создай ключ HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\ FORMATS\TIME\MILSECONDS=TRUE Alexey Yashin (2:5020/62.31) . Q>: Как создать Calculated Fields в RunTime? A>: See book "Developing Custom Delphi Components" by Ray Konopka. This is little bit corrected example from this book: function TMyClass.CreateCalcField( const AFieldName:string; AFieldClass:TFieldClass; ASize:Word ) : TField; begin Result := FDataSet.FindField(AFieldName); // Field may already exists! if Result<>nil then Exit; if AFieldClass=nil then DBErrorFmt( SUnknownFieldType, [AFieldName] ); Result := FieldClass.Create(Owner); with Result do try FieldName := AFieldName; if (Result is TStringField) or (Result is TBCDField) or (Result is TBlobField) or (Result is TBytesField) or (Result is TVarBytesField) then Size := ASize; Calculated := True; DataSet := FDataset; Name := FDataSet.Name+AFieldName; except Free; // We must release allocated memory on error! raise; end; end; Alex Konshin (2:5030/217.217) . Q>: Как создать новый запрос и скопировать туда точно такие же описания полей? A>: Копируешь FieldDefs. Проходишь циклом по FieldDefs.Items[i].CreateField(Owner); Alex Konshin (2:5030/217.217) . Q>: (DB2) Почему DB2 ругается на Create Trigger? A>: Я тут писал по поводу того, что у меня не pаботали тpиггеpы. Все дело оказалось в пpавиле написания команды "create trigger". Если все остальные команды коppектно воспpинимаются на любом pегистpе, то эта только набpанная одними большими буквами. Aleksey Sushko (2:4615/7.32) . Q>: (IB) Как заставить Interbase принять COLLATE PXW_CYRL по умолчанию? (AA: Это очень полезно при прямой работе с IB из PowerDesigner) A>: Чтобы не писать каждый раз COLLATE я сделал следующее: 1) Создал сохраненную процедуру create procedure fix_character_sets as begin update rdb$character_sets set rdb$default_collate_name = 'PXW_CYRL' where rdb$character_set_name = 'WIN1251' and rdb$default_collate_name = 'WIN1251'; end 2) Запустил ее один раз. 3) Создаю таблицы без COLLATE. 4) После восстановления из архива, запускаю еще раз. Кудрин Олег, АТС-55, Красноярск. oleg@ats.telecom.krasnoyarsk.su . Q>: Есть некоторая таблица и требуется при нажатии на кнопку создавать таблицы такой же структуры, подскажите как это удобнее всего сделать. A>: Удобней всего, напpимеp, так - with bmovMyBatchMove do begin Mode := bmCopy; RecordCount := 1; Execute; Destination.Delete; end; Akzhan Abdulin (2:5040/55.46) Неправда Ваша! ;) Этот загадочный BatchMove имеет одну очень неприятную особенность (по крайней мере при работе с DBF таблицами и в D1), как-то: увеличивает в создаваемых таблицах в полях типа NUMBER количество значащих цифирей после запятой (не помню - возможно, что и до), если там указаны небольшие (~ 1-3 цифр) значения :(. Я эту особенность побороть не сумел, а мириться с ней в условиях нашей конторы (когда приходится бороться за место под солнцем с программистами на Clipper и FoxPro совершенно неприемлимо. Кроме того, в предложенном выше варианте еще и запись удалять приходится...:) Решалась же эта проблема следующим способом: >============ Cut Begin Myutils.Pas ==================== procedure CopyStruct(SrcTable,DestTable: TTable; cpyFields: array of string); var i: Integer; bActive: Boolean; SrcDatabase,DestDatabase: TDatabase; iSrcMemSize,iDestMemSize: Integer; pSrcFldDes: PFldDesc; CrtTableDesc: CRTblDesc; bNeedAllFields: Boolean; begin SrcDatabase:=Session.OpenDatabase(SrcTable.DatabaseName); try DestDatabase:=Session.OpenDatabase(DestTable.DatabaseName); try bActive:=SrcTable.Active; SrcTable.FieldDefs.Update; iSrcMemSize:=SrcTable.FieldDefs.Count*SizeOf(FLDDesc); pSrcFldDes:=AllocMem(iSrcMemSize); if pSrcFldDes = nil then raise EOutOfMemory.Create('=х iтрEрхE ярь Eш!'); try SrcTable.Open; Check(DbiGetFieldDescs(SrcTable.Handle,pSrcFldDes)); SrcTable.Active:=bActive; FillChar(CrtTableDesc,SizeOf(CrtTableDesc),0); with CrtTableDesc do begin StrPcopy(szTblName,DestTable.TableName); StrPcopy(szTblType,'DBASE'); if(Length(cpyFields[0]) = 0) or (cpyFields[0] = '*') then begin bNeedAllFields:=True; SrcTable.FieldDefs.Update; iFldCount:=SrcTable.FieldDefs.Count; end else begin bNeedAllFields:=False; iFldCount:=High(cpyFields)+1; end; iDestMemSize:=iFldCount*Sizeof(FLDDesc); CrtTableDesc.pFLDDesc:=AllocMem(iDestMemSize); if CrtTableDesc.pFLDDesc = nil then raise EOutOfMemory.Create('=х iтрEрхE ярь Eш!'); end; try if bNeedAllFields then for i:=0 to CrtTableDesc.iFldCount-1 do Move(PFieldDescList(pSrcFldDes)^[i], PFieldDescList(CrtTableDesc.pFLDDesc)^[i],SizeOf(FldDesc)) else for i:=0 to CrtTableDesc.iFldCount-1 do Move(PFieldDescList(pSrcFldDes)^[SrcTable.FieldDefs.Find(cpyField s[i]).FieldNo-1], PFieldDescList(CrtTableDesc.pFLDDesc)^[i],SizeOf(FldDesc)); Check(DbiCreateTable(DestDatabase.Handle,True,CrtTableDesc)); finally FreeMem(CrtTableDesc.pFLDDesc,iDestMemSize); end; finally FreeMem(pSrcFldDes,iSrcMemSize); end; finally Session.CloseDatabase(DestDatabase); end; finally Session.CloseDatabase(SrcDatabase); end; end; >============ Cut End ==================== Vlad Fillippov (2:5055/34.3) . Q>: (SAW) Как бы мне соорудить в SP исключение, чтобы его увидел Delphi-клиент? A>: SS> sqlstate='99999' не подходит, т.к. хочется на клиенте видеть код SS> исключения. Используй RAISERROR с кодом >20000. Если еще пpи этом научишься без потеpь пеpедавать на Delphi-клиента pусские pугательства, то скажи мне как ты этого добился :). У меня для этого pаботает pедкостный извpат, даже людям показать стыдно :). Alexander Tesanov (2:5015/23.5) .
Секция 3 из 3 - Предыдущая - Следующая
Вернуться в раздел "Языки Pascal/Delphi" - Обсудить эту статью на Форуме |
Главная - Поиск по сайту - О проекте - Форум - Обратная связь |