Главная > Программирование > Языки Pascal/Delphi > |
FAQ по работе с СУБД на Delphi |
Секция 1 из 3 - Предыдущая - Следующая
Все секции
- 1
- 2
- 3
Title> Полезные советы по работе с СУБД, ориентированные на разработчиков среды Delphi, собранные Акжаном Абдулиным Keyword> Delphi Tip Trick DB DBMS VCL В общем, pешил я FAQlist составить еще один :) Вpемя будет, буду обновлять. Со всеми дополнениями, замечаниями и похвалами обpащаться Akzhan Abdulin 2:5040/55@fidonet.org > в данном контексте: PK (Primary Key) - первичный ключ; FK (Foreign Key) - ключ; SP (Stored Procedure) - хранимая процедура; UDF (User Defined Function) - определенная пользователем процедура, обычно в виде или в составе выполнимого модуля или скрипта (Rexx, Ticl, Perl etc.). > сокращения продуктов: SAW - Sybase SQLAnywhere, бывший Watcom SQL Server www.sybase.com, www.sybase.ru DB2 - IBM DB2 www.ibm.com, www.ibm.ru UDB - New generation of DB2, v5 Universal DataBase. IB - Interbase, В России известен также так IBDatabase www.interbase.com, www.inprise.com, www.borland.ru, www.demo.ru, ib.demo.ru MSSQL - MS SQL Server www.microsoft.com/sqlserver DESK - "настольные" БД, Paradox и dBase PDX - Corel Paradox www.corel.com, www.inprise.com DBF - xBase www.borland.com (Borland Visual dBase) FIB - FreeIBComponents BDE - Borland Database Engine > --- added in v7.0 Q>: Делаем ApplyUpdates. Если пpи insert(update) пpоизошла ошибка (поле null, сpаботал check, etc), то BDE всегда говоpит "General SQL Error" вместо ноpмального сообщения об ошибке :-( Без CU все ноpмально, pазумеется. Как боpоть этот баг? A>: Использyй ноpмальнyю тpансляцию ошибок в Application.OnException. Вpоде это. >== Режем pаз ==< procedure DBExceptionTranslate(E: EDBEngineError); function OriginalMessage: String; var I: Integer; DBErr: TDBError; S: String; begin Result := ''; for I := 0 to E.ErrorCount - 1 do begin DBErr := E.Errors[I]; case DBErr.NativeError of -836: { Intebase exception } begin S := DBErr.Message; Result := #13#10 + Copy(S, Pos(#10, S) + 1, Length(S)); Exit; end; end; S := Trim(DBErr.Message); if S <> '' then Result := Result + #13#10 + S; end; end; begin case E.Errors[0].ErrorCode of $2204: E.Message := LoadStr(SKeyDeleted); $271E,$2734: E.Message := LoadStr(SInvalidUserName); $2815: E.Message := LoadStr(SDeadlock); $2601: E.Message := LoadStr(SKeyViol); $2604: E.Message := LoadStr(SFKViolation) + OriginalMessage; else begin E.Message := Format(LoadStr(SErrorCodeFmt), [E.Errors[0].ErrorCode]) + OriginalMessage; end; end; end; >== Режем два ==< Vladimir Gaitanoff vg@divo.ru www.tsinet.ru/~vg (2:5017/5.69) . Q>: [IB] Как узнать текущие дату и время в Interbase? A>: Дата + время - DATE. Только дата - TODAY. Только время - DATE-TODAY. Сяржук Казачэнка bamboo7431@hotmail.com . Q>: [IB] После снесения через родной uninstall Interbase Server 5.0 для Windows и желания поставить 5.1.1 вылетает ошибка: IBCheck. Что делать? A>: Решение найдено. Прочитай сам и передай товарищу: надо запустить regedit, и открыть ключ HKEY_LOCAL_MACHINE\Environment там есть строка PATH. Так вот иногда она почему-то становится не строкой, а еще чем-то. Ее надо убить, и пересоздать как строку, прописав туда прежнее содержимое (в виде строки). Dmitry Kuzmenko, Epsylon Technologies. dima@demo.ru . Q>: [DBF] Как можно открыть DBF-файл с признаком индекса, если индексный файл отсутствует? A>: С помощью BDE Callbacks. Пpимеp для Delphi 2.0, на пеpвом не пpовеpял: === Callback.pas === unit Callback; interface uses BDE, Classes, Forms, DB, DBTables; type TForm1 = class(TForm) Table1: TTable; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private CBack: TBDECallback; // опpеделение BDE CallBack CBBuf: CBInputDesc; // пpосто буфеp function CBFunc(CBInfo: Pointer): CBRType; // Callback-функция public end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin Session.Open; // В это вpемя сессия ещё не откpыта CBack := TBDECallback.Create(Session {Напpимеp},nil,cbINPUTREQ,@CBRegBuf, SizeOf(CBBuf),CBFunc,False); // Опpеделили Callback Table1.Open; //^^^^^^^^^^^ - здесь возможна ошибка с индексом, etc. end; procedure TForm1.FormDestroy(Sender: TObject); begin CBack.Free; // Освобождаем CallBack end; function TForm1.CBFunc(CBInfo: Pointer): CBRType; begin with PCBInputDesc(CBInfo)^ do case eCbInputId of cbiMDXMissing {, cbiDBTMissing - можно ещё и очищать BLOB-поля}: begin iSelection := 3; // Номеp ваpианта ответа (1-й - откpыть только // для чтения, 2-й - не откpывать, 3-й - отсоединить индекс). // Возможный источник непpиятностей: а вдpуг в последующих веpсиях // BDE номеpа будут дpугими? Result := cbrCHKINPUT; // Обpабатывать введённый ответ end; end; end; end. === Callback.pas === PS: конечно, это лишь пpимеp, делающий минимум необходимого. В pамках данного письма невозможно дать какое-то описание BDE Callbacks. Инфоpмацию я взял из BDE32.HLP, BDE.INT и DB.PAS. В VCL.HLP совсем ничего нет по этому поводу. Вообще, pуки бы отоpвал тем, кто писал спpавку по Дельфям: я неделю мучался с сабжем, пока случайно не набpёл на Callbacks. Denis Zaytsev (2:5011/49.6) . > --- changed in v7.0 Q>: Как работать из Delphi напрямую с MS ADO (Microsoft Active Data Objects)? A>: Итак, хочу поделиться некоторыми достижениями... так на всякий случай. Если у вас вдруг потребуется сделать в своей программке доступ к базе данных, а BDE использовать будет неохота (или невозможно) - то есть довольно приятный вариант: использовать ActiveX Data Objects. Однако с их использованием есть некоторые проблемы, и одна из них это как передавать Optional параметры, которые вроде как можно не указывать. Однако, если вы работаете с ADO по-человечески, а не через тормозной IDispatch.Invoke то это превращается в головную боль. Вот как от нее избавляться: var OptionalParam: OleVariant; VarData: PVarData; begin OptionalParam := DISP_E_PARAMNOTFOUND; VarData := @OptionalParam; VarData^.VType := varError; после этого переменную OptionalParam можно передавать вместо неиспользуемого аргумента. Далее, самый приятный способ получения Result sets: Там есть масса вариантов, но как выяснилось оптимальным является следующий вариант, который позволяет получить любой желаемый вид курсора (как клиентский так и серверный) var MyConn: _Connection; MyComm: _Command; MyRecSet: _Recordset; prm1: _Parameter; begin MyConn := CoConnection.Create; MyConn.ConnectionString := 'DSN=pubs;uid=sa;pwd=;'; MyConn.Open('','','',-1); MyCommand := CoCommand.Create; MyCommand.ActiveConnection := MyConn; MyCommand.CommandText := 'SELECT * FROM blahblah WHERE BlahID=?' Prm1 := MyCommand.CreateParameter('Id',adInteger.adParamInput,-1,<value>); MyCommand.AppendParameter(Prm1); MyRecSet := CoRecordSet.Create; MyRecSet.Open(MyCommand,OptionalParam,adOpenDynamic,adLockReadOnly,adCmdText); ... теперь можно фетчить записи. Работает шустро и классно. Меня радует. Особенно радуют серверные курсоры. Проверялось на Delphi 3.02 + ADO 1.5 + MS SQL 6.5 sp4. Пашет как зверь. Из вкусностей ADO - их легко можно использовать во всяких многопоточных приложениях где BDE порой сбоит, если, конечно, ODBC драйвер грамотно сделан... ну и еще можно использовать для доступа к данным всяких там "нестандартных" баз типа MS Index Server или MS Active Directory Services. Alexey Kopernick awk@dialup.ptt.ru ICQ UIN: 3150119 (2:5020/221) В Delphi (как минимум в 4 версии) существует "константа" EmptyParam, которую можно подставлять в качестве пустого параметра. Akzhan Abdulin (2:5040/55.46) . > --- added in v6 Q>: Как установить BDE32 на чистой машине (ручками, без IS)? A>: Нижеследующий рецепт работает для вариантов D2/BDE351, D3/BDE40, D3/BDE451, D2/BDE40, D2/BDE451. Список файлов BDE для версии 3.51 (в отличие от 4.x) также не вычислял; считаем, что необходимы все файлы. 1. Переписать все файлы: // ========== BDE40 =================== CHARSET.BLL OTHER.BLL USA.BLL IDAPI32.CFG BLW32.DLL IDAPI32.DLL IDBAT32.DLL IDPDX32.DLL IDR20009.DLL IDSQL32.DLL BDEADMIN.EXE // ========== end of BDE40 =================== 2. Прописать в регистри след. значения: // ==========BDE351 =================== REGEDIT4 [HKEY_LOCAL_MACHINE\SOFTWARE\Borland] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\BLW32] "LOCALE_LIB1"="C:\\Program Files\\Borland\\Common Files\\BDE\\USA.BLL" "BLAPIPATH"="C:\\Program Files\\Borland\\Common Files\\BDE" "LOCALE_LIB2"="C:\\Program Files\\Borland\\Common Files\\BDE\\EUROPE.BLL" "LOCALE_LIB3"="C:\\Program Files\\Borland\\Common Files\\BDE\\OTHER.BLL" "LOCALE_LIB4"="C:\\Program Files\\Borland\\Common Files\\BDE\\CHARSET.BLL" "LOCALE_LIB5"="C:\\Program Files\\Borland\\Common Files\\BDE\\CEEUROPE.BLL" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine] "DLLPATH"="C:\\Program Files\\Borland\\Common Files\\BDE" "CONFIGFILE01"="C:\\Program Files\\Borland\\Common Files\\BDE\\IDAPI32.CFG" "RESOURCE"="Path=BDE_LANGDRV" "SaveConfig"="WIN31" "UseCount"="1" // ========== End of BDE351 =================== // ========== BDE40 =================== REGEDIT4 [HKEY_LOCAL_MACHINE\SOFTWARE\Borland] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine] "DLLPATH"="C:\\APartner\\BDE451\\SQLLinks.40;C:\\APartner\\BDE451" "RESOURCE"="0009" "CONFIGFILE01"="C:\\APartner\\BDE451\\IDAPI32.CFG" "UseCount"="1" "SaveConfig"="WIN32" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE\INIT] "VERSION"="4.0" "TYPE"="FILE" "LANGDRIVER"="db866ru0" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE\TABLE CREATE] "LEVEL"="5" "MDX BLOCK SIZE"="1024" "MEMO FILE BLOCK SIZE"="1024" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\MSACCESS] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\MSACCESS\DB OPEN] "DATABASE NAME"="DRIVE:/PATH/DATABASE.MDB" "USER NAME"="" "OPEN MODE"="READ/WRITE" "LANGDRIVER"="" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\MSACCESS\INIT] "VERSION"="1.0" "TYPE"="SERVER" "DLL32"="IDDAO32.DLL" "DRIVER FLAGS"="" "TRACE MODE"="0" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\ORACLE] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\ORACLE\DB OPEN] "SERVER NAME"="ORA_SERVER" "USER NAME"="MYNAME" "NET PROTOCOL"="TNS" "OPEN MODE"="READ/WRITE" "SCHEMA CACHE SIZE"="8" "LANGDRIVER"="" "SQLQRYMODE"="" "SQLPASSTHRU MODE"="SHARED AUTOCOMMIT" "SCHEMA CACHE TIME"="-1" "MAX ROWS"="-1" "BATCH COUNT"="200" "ENABLE SCHEMA CACHE"="FALSE" "SCHEMA CACHE DIR"="" "ENABLE BCD"="FALSE" "ENABLE INTEGERS"="FALSE" "LIST SYNONYMS"="NONE" "ROWSET SIZE"="20" "BLOBS TO CACHE"="64" "BLOB SIZE"="32" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\ORACLE\INIT] "VERSION"="4.0" "TYPE"="SERVER" "DLL"="SQLD_ORA.DLL" "DLL32"="SQLORA32.DLL" "VENDOR INIT"="ORANT71.DLL" "DRIVER FLAGS"="" "TRACE MODE"="0" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\PARADOX] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\PARADOX\INIT] "VERSION"="4.0" "TYPE"="FILE" "LANGDRIVER"="ancyrr" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\DRIVERS\PARADOX\TABLE CREATE] "LEVEL"="4" "BLOCK SIZE"="2048" "FILL FACTOR"="95" "STRICTINTEGRTY"="TRUE" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\REPOSITORIES] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\REPOSITORIES\Borland Data Dictionary] "DATABASE NAME"="DefaultDD" "TABLE NAME"="BDESDD" "LANGUAGE DRIVER"="" "DESCRIPTION"="Borland Database Engine Sample Data Dictionary" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\FORMATS] [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\FORMATS\DATE] "SEPARATOR"="." "MODE"="1" "FOURDIGITYEAR"="FALSE" "YEARBIASED"="TRUE" "LEADINGZEROM"="FALSE" "LEADINGZEROD"="FALSE" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\FORMATS\NUMBER] "DECIMALSEPARATOR"="." "THOUSANDSEPARATOR"=" " "DECIMALDIGITS"="2" "LEADINGZERON"="TRUE" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\FORMATS\TIME] "TWELVEHOUR"="FALSE" "AMSTRING"="AM" "PMSTRING"="PM" "SECONDS"="TRUE" "MILSECONDS"="FALSE" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\INIT] "VERSION"="4.0" "LOCAL SHARE"="FALSE" "MINBUFSIZE"="128" "MAXBUFSIZE"="2048" "LANGDRIVER"="ancyrr" "MAXFILEHANDLES"="48" "SYSFLAGS"="0" "LOW MEMORY USAGE LIMIT"="32" "AUTO ODBC"="FALSE" "DEFAULT DRIVER"="PARADOX" "MEMSIZE"="16" "SHAREDMEMSIZE"="2048" "SHAREDMEMLOCATION"="" "DATA REPOSITORY"="Borland Data Dictionary" "SQLQRYMODE"="" [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\BLW32] "BLAPIPATH"="C:\\APartner\\BDE451" "LOCALE_LIB1"="C:\\APartner\\BDE451\\USA.BLL" "LOCALE_LIB2"="C:\\APartner\\BDE451\\EUROPE.BLL" "LOCALE_LIB3"="C:\\APartner\\BDE451\\OTHER.BLL" "LOCALE_LIB4"="C:\\APartner\\BDE451\\CHARSET.BLL" "LOCALE_LIB5"="C:\\APartner\\BDE451\\CEEUROPE.BLL" "LOCALE_LIB6"="C:\\APartner\\BDE451\\FAREAST.BLL" "LOCALE_LIB7"="C:\\APartner\\BDE451\\JAPAN.BLL" // ========== End of BDE40 =================== Serge Sushko sushko@apartner.aha.ru http://members.tripod.com/~sushko/ . Q>: Как засунуть в качестве паpаметpа хpанимой пpоцедуpы стpоку длиной более 255 символов? И вообще, как использовать паpаметpы SP, если они BLOB? A>: "засунуть" длинную строку можно было и раньше, если написать редактируемый запрос, и воспользоваться операциями Insert/Edit. Однако это не относится к хранимым процедурам. В Delphi 3.0 появился новый тип параметра (TBlobField вроде) и соответственно его поддержка в BDE. Если просто взять BDE 4.01 и выше, то работать все-равно не будет - нужна соотв. версия VCL (из Delphi 3.0 или выше) Dmitry Kuzmenko, Epsylon Technologies. (095) 535-0319, 913-5608. http://ib.demo.ru/ Q>: [PDX] Почему при создании таблицы Paradox с первичным нечувствительным к регистру индексом вываливается ошибка? A>: В Парадоксе первичный индекс всегда CaseSensitive. <имя автора не сохранилось> . > --- changed in v6 Q>: [PDX,DBF] Как программно изменить LangDriver для таблиц dBase и Paradox? A>: Откpываешь help и смотpишь: ....... var List:TStrings; ....... BEGIN ....... List.Add ('LANGDRIVER=db866ru0'); ....... Session.ModifyDriver('DBASE',List); ....... END; это действие я пpовожy пеpед откpытием таблицы Ivan Sboev (2:5049/36.15) Это о "русификации" таблицы. В таблицах dBase и Paradox имеется байт, который определяет CodePage содержимого таблицы. Раньше он не использо- вался и был зарезервирован. Тебе нужно его правильно установить. Это делается через DBD Restructure table. Если хочешь програмно, можешь воспользоваться следующей процедурой: uses DbiTypes, DbiProcs, DbiErrs, DB, WinProcs, SysUtils; procedure ChangeLangDriver(DatabaseName, TableName, LDName: string); var TblExt: string; Database: TDatabase; TblDesc: CRTblDesc; OptDesc: FLDDesc; OptData: array [0..250] of Char; Cur: hDBICur; Rec: CFGDesc; begin if (TableName='') or (LDName='') then raise Exception.Create('Unknown TableName or LDName'); Database:=Session.OpenDatabase(DatabaseName); try if Database.IsSQLBased then raise Exception.Create('Function ChangeLangDriver working only with dBase or Paradox tables'); FillChar(OptDesc, SizeOf(OptDesc), #0); FillChar(TblDesc, SizeOf(TblDesc), #0); StrCopy(OptDesc.szName, 'LANGDRIVER'); OptDesc.iLen:=Length(LDName)+1; with TblDesc do begin StrPCopy(szTblName, TableName); TblExt:=UpperCase(ExtractFileExt(TableName)); if TblExt='DBF' then StrCopy(szTblType, szDbase) else if TblExt='.DB' then StrCopy(szTblType, szParadox) else begin AnsiToOEM(StrPCopy(OptData, DatabaseName), OptData); if DbiOpenCfgInfoList(nil, dbiREADONLY, cfgPersistent, StrPCopy(OptData, '\DATABASES\'+StrPas(OptData)+'\DB INFO\'), Cur)<>DBIERR_NONE then raise Exception.Create('Unknown table type'); try while DbiGetNextRecord(Cur, dbiNOLOCK, @Rec, nil)<>DBIERR_EOF do if StrComp(Rec.szNodeName, 'DEFAULT DRIVER')=0 then begin StrCopy(szTblType, Rec.szValue); Break; end; finally Check(DbiCloseCursor(Cur)); end; end; iOptParams:=1; pfldOptParams:=@OptDesc; pOptData:=@OptData; end; StrPCopy(OptData, LDName); Check(DbiDoRestructure(Database.Handle, 1, @TblDesc, nil, nil, nil, False)); finally Session.CloseDatabase(Database); end; end; Примеры использования: ChangeLangDriver('DBDEMOS', 'EMPLOYEE', 'ancyrr'); ChangeLangDriver('DBDEMOS', 'EMPLOYEE.DB', 'ancyrr'); ChangeLangDriver('C:\DELPHI\DEMOS\DATA', 'CLIENTS.DBF', 'db866ru0'); LDName: для D1 - имя .LD файла в каталоге IDAPI\LANGDRV для D2 и CB - из BDECFG32.HLP поле Short name в табличке по указателю language drivers, dBASE или поле Internal в табличке по указателю language drivers, Paradox. для D3 - не знаю так как у меня ее нет, думаю, что как и в D2. Farid Zaripov farid@aduis.kiev.ua (2:463/201.101) . > --- added in v5.1 Q>: [Oracle] Поясните, чем в Oracle являются понятия Instance, Database etc.? A>: Перевод документации: ------------------------------------------------------------------------------ Q: Что такое ORACLE Database? A: Это данные которые будут обрабатываться как единое целое. Database состоит из файлов операционной системы. Физически существуют database files и redo log files. Логически database files содержат словари, таблицы пользователей и redo log файлы. Дополнительно database требует одну или более копий control file. Q: Что такое ORACLE Instance? A: ORACLE Instance обеспечивает программные механизмы доступа и управления database. Instance может быть запущен независимо от любой database (без монтирования или открытия любой database). Один instance может открый только одну database. В то время как одна database может быть открыта несколькими Instanse. Instance состоит из: 1) SGA (System Global Area) которая обеспечивает коммуникацию меджу процессами 2) до пяти (в последних версиях больше) бэкграундовых процессов. ----------------------------------------------------------------------------- От себя добавлю - database включает в себя tablespace, tablespace включает в себя segments (в одном файле данных может быть один или несколько сегментов, сегменты не могут быть разделены на несколько файлов). segments включают в себя extents. Alex Kravets (2:5020/904.12) . Q>: [DB2+UDB] Существует ли средство для вывода определения структуры таблицы? Я создал таблицу и хочу получить её структуру, чтобы сделать изменённый оператор создания таблицы. A>: Для этого существует утилита DB2LOOK. Она находится в SQLLIB\MISC. Пример использования: CONNECT TO SAMPLE USER xxx USING yyy DB2LOOK -d SAMPLE -u xxx -e -t employee Вывод может быть перенаправлен в файл. Полный синтаксис выдаётся по команде: DB2LOOK ? Vadim Rumyantsev (2:5030/48.400) . Q>: [DB2+UDB] У меня есть текстовые файлы, которые я хочу использовать в запросах к DB2, но не хочу создавать из них постоянные таблицы в базе. Что делать? A>: Можно воспользоваться табличными функциями (Table Functions). Они позволяют использовать файлы как таблицы. Примеры приведены в руководстве "Embedded SQL Programming Guide". Vadim Rumyantsev (2:5030/48.400) . > --- added in v5 Q>: [Oracle] Как заставить Oracle анализировать все таблицы базы данных? A>: Конечно, можно использовать DBMS_SQL, DBMS_JOB... А можно и так: #!/bin/sh # # Analyze all tables # SQLFILE=/tmp/analyze.sql LOGFILE=/tmp/analyze.log echo @connect dbo/passwd@ > $SQLFILE $ORACLE_HOME/bin/svrmgrl <<EOF | awk \ '/^TABLE/ { print "ANALYZE TABLE DBO." $2 \ " ESTIMATE STATISTICS"; print "/"; }' >> $SQLFILE connect dbo/passwd SELECT 'TABLE', TABLE_NAME FROM all_tables WHERE owner = 'DBO'; EOF echo exit >> $SQLFILE cat $SQLFILE > $LOGFILE cat $SQLFILE | $ORACLE_HOME/bin/svrmgrl >> $LOGFILE cat $LOGFILE | /usr/bin/mailx -s 'Analyze tables' tlk@nbd.kis.ru rm $SQLFILE rm $LOGFILE Anatoly Kuznetsov tlk@nbd.kis.ru (2:5015/4.1) . Q>: [Oracle] В режиме отладки приложения не разрешается доступ (открытие) базы данных. Как лечить? A>: Необходимо отключить (деинсталлировать через Oracle Installer) Trace Service на клиенте - совет от ORACLE. Глюк имеет место быть только под Windows NT 4.xx. Sergey Klochkovski (2:5080/60.3) . Q>: [VCL] При разрушении обьектов, порожденных от TDataSet (TTable, TQuery), не отрабатывает событие OnBeforeClose. Что делать? A>: Сейчас вышел из ситуации так: в TForm.OnClose, т.е. пока ещё все компоненты формы живы, делаю CloseDatabases(Self). Александр Петросян(PAF), Зеленоград. (2:5020/468.8) . Q>: [SQL] При попытке выполнения такого оператора SQL - "DELETE from T39 T39C0 WHERE T39C0.F1LHT35=253291661" SQL-сервер ругается на недопустимый синтаксис. В чем я неправ? A>: В данном случае, видимо, T39C0 расценивается как псевдоним. Но стандартом SQL-92 такое запрещено в delete. Цитата собственно из этого стандарта (сборник из delete и names and identifiers, определение identifier пропущено, просто набор <simple latin letter> | <digit>, начинается с буквы): Format <delete statement: positioned>::= delete from <table name> where current of <cursor name> <table name> ::= <qualified name> | <qualified local name> <qualified name> ::= [<shema name><period>] [<qualified identifier>] <qualified identifier> ::=<identifier> <shema name>::=[<catalog name><period>]<unqualified shema name> <unqualified shema name>::=<identifier> <catalog name>::=<identifier> <qualified local name>::= MODULE <period><local table name> <local table name>::=<qualified identifier> Стандартом запрещено вот такое select test.a, p_test.a from test p_test; вот это не по стандарту, хотя MS такое ест. Lilya Kozlenko li@relex.ru . Q>: [VCL] Хочу шапку в TDBGrid. Как сделать? A>: Уже реализовано в виде вот этого компонента - (С) Andre unit bdbgrid; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids, DBGrids, Math; type TOnDrawTitleEvent = procedure(ACol : integer; ARect : TRect; var TitleText : string) of object; TBitDBGrid = class(TDBGrid) private FBitmapBrowse : TBitmap; FBitmapEdit : TBitmap; FBitmapInsert : TBitmap; FBitmapFill : TBitmap; FRealTitleFont : TFont; FOnDrawTitle : TOnDrawTitleEvent; FResizeFlag : boolean; { Private declarations } procedure SetRealTitleFont(Value : TFont); procedure UpdateTitlesHeight; protected procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; { Protected declarations } public constructor Create(AOwner : TComponent);override; destructor Destroy; override; { Public declarations } published property OnDrawTitle : TOnDrawTitleEvent read FOnDrawTitle write FOnDrawTitle; property RealTitleFont : TFont read FRealTitleFont write SetRealTitleFont; { Published declarations } end; procedure Register; implementation var DrawBitmap : TBitmap; function Max(X, Y: Integer): Integer; begin Result := Y; if X > Y then Result := X; end; procedure WriteText(ACanvas: TCanvas; ARect: TRect; DX, DY: Integer; const Text: string; Alignment: TAlignment); //(C) Borland function :) const AlignFlags : array [TAlignment] of Integer = ( DT_LEFT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX, DT_RIGHT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX, DT_CENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX ); var B, R: TRect; I, Left: Integer; begin with DrawBitmap, ARect do { Use offscreen bitmap to eliminate flicker and } begin { brush origin tics in painting / scrolling. } Width := Max(Width, Right - Left); Height := Max(Height, Bottom - Top); R := Rect(DX, DY, Right - Left - 1, Bottom - Top - 1); B := Rect(0, 0, Right - Left, Bottom - Top); end; with DrawBitmap.Canvas do begin DrawBitmap.Canvas.CopyRect(B, ACanvas, ARect); Font := ACanvas.Font; Font.Color := ACanvas.Font.Color; Brush := ACanvas.Brush; SetBkMode(Handle, TRANSPARENT); DrawText(Handle, PChar(Text), Length(Text), R, AlignFlags[Alignment]); end; ACanvas.CopyRect(ARect, DrawBitmap.Canvas, B); end; constructor TBitDBGrid.Create(AOwner : TComponent); begin inherited Create(Aowner); FRealTitleFont := TFont.Create; FResizeFlag := false; end; destructor TBitDBGrid.Destroy; begin FRealTitleFont.Free; inherited Destroy; end; procedure TBitDBGrid.UpdateTitlesHeight; var Loop : integer; MaxTextHeight : integer; RRect : TRect; begin MaxTextHeight := 0; for loop := 0 to Columns.Count - 1 do begin RRect := CellRect(0, 0); RRect.Right := Columns[Loop].Width; RRect.Left := 0; Canvas.Font := RealTitleFont; MaxTextHeight := Max(MaxTextHeight, DrawText(Canvas.Handle, PChar(Columns[Loop].Title.Caption), Length(Columns[Loop].Title.Caption), RRect, DT_CALCRECT + DT_WORDBREAK)); end; if TitleFont.Height <> - MaxTextHeight then TitleFont.Height := - MaxTextHeight; end; procedure TBitDBGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if MouseCoord(X, Y).Y = 0 then FResizeFlag := true; inherited MouseDown(Button, Shift, X, Y); end; procedure TBitDBGrid.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin inherited MouseUp(Button, Shift, X, Y); if FResizeFlag then begin FResizeFlag := false; UpdateTitlesHeight; end; end; procedure TBitDBGrid.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); var Indicator : TBitmap; TitleText : string; Al : TAlignment; begin if not ((gdFixed in AState) and ((ARow = 0) and (dgTitles in Options) and (ACol <> 0))) then inherited DrawCell(ACol, ARow, ARect, AState) else begin if DefaultDrawing then begin DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_BOTTOMLEFT); DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_TOPRIGHT); InflateRect(ARect, -1, -1); Canvas.Brush.Color := FixedColor; Canvas.FillRect(ARect); end; TitleText := Columns[ACol - 1].Title.Caption; if Assigned(OnDrawTitle) then OnDrawTitle(ACol, ARect, TitleText); if DefaultDrawing and (TitleText <> '') then begin Canvas.Brush.Style := bsClear; Canvas.Font := RealTitleFont; if ACol > 0 then Al := Columns[ACol - 1].Title.Alignment else Al := Columns[0].Title.DefaultAlignment; WriteText(Canvas, ARect, 2, 2, TitleText, Al); end; end; end; procedure TBitDBGrid.SetRealTitleFont(Value : TFont); begin FRealTitleFont.Assign(Value); Repaint; end; procedure Register; begin RegisterComponents('Andre VCL', [TBitDBGrid]); end; initialization DrawBitmap := TBitmap.Create; finalization DrawBitmap.Free; end. Ilya Andreev . Q>: [IB] При обращении к memo-полю из BDE возникает ошибка "Memo too large". Как лечить? A>: В BDE есть крутая ошибка, достаточно известная всем, кроме Borland'a. Поскольку они ее еще с 1й Delphi не исправили. Этот баг проявляется как Access Violation в программе при обращении к таблице IB, которая содержит более одного поля типа VARCHAR (или CHAR) размером > 255. Причем, первое поле меньшего, а второе большего размера. Если поменять местами поля или сделать их одного размера, то все нормально. Эффект имеет место только с IB, вроде. Вадим Миллер miller@demo.ru . Q>: [PDX] Как сменить пароль (master password) для таблицы Paradox? A>: пожалуйста: var db : TDatabase; Desc : CRTblDesc; begin db := PriceTable.OpenDatabase; FillChar( Desc, SizeOf( Desc ), #0 ); StrCopy( Desc.szTblName, PChar(PriceTable.TableName)); StrCopy( Desc.szTblType, szParadox ); StrCopy( Desc.szPassword, 'password' ); Desc.bProtected := TRUE; Check( DbiDoRestructure( db.Handle, 1, @Desc, nil, nil, nil, FALSE )); end; Садохин Дмитрий (SDV) vita@transit.samara.ru . Q>: [MSSQL] Работаю на D3+BDE+ODBC и если в транзакции изменена какая-то таблица,
Секция 1 из 3 - Предыдущая - Следующая
Вернуться в раздел "Языки Pascal/Delphi" - Обсудить эту статью на Форуме |
Главная - Поиск по сайту - О проекте - Форум - Обратная связь |