> в данном контексте:
PK (Primary Key) - первичный ключ;
FK (Foreign Key) - ключ;
SP (Stored Procedure) - хранимая процедура;
UDF (User Defined Function) - определенная пользователем процедура, обычно
в виде или в составе выполнимого модуля или скрипта (Rexx, Ticl, Perl etc.).
> сокращения продуктов:
SAW - Sybase SQLAnywhere, бывший Watcom SQL Server
wwwsybase.com, wwwsybase.ru
DB2 - IBM DB2
wwwibm.com, wwwibm.ru
UDB - New generation of DB2, v5 Universal DataBase.
IB - Interbase, В России известен также так IBDatabase
wwwinterbase.com, wwwinprise.com, wwwborland.ru, wwwdemo.ru, ib.demo.ru
MSSQL - MS SQL Server
wwwmicrosoft.com/sqlserver
DESK - "настольные" БД, Paradox и dBase
PDX - Corel Paradox
wwwcorel.com, wwwinprise.com
DBF - xBase
wwwborland.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
wwwtsinet.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 и если в транзакции изменена какая-то таблица,
то для другого пользователя блокируестя вся таблица, до окончания транзакции.
Как лечить?
A>:
По умолчанию, оператор UPDATE в MS SQL Server пытается поставить эксклюзивную
табличную блокировку. Вы можете обойти это, используя ключевое слово FROM в
сочетании с опцией PAGLOCK для использования MS SQL Server страничных
блокировок вместо эксклюзивной табличной блокировки:
UPDATE orders SET customer_id=NULL FROM orders(PAGLOCK) WHERE customer_id=32;
(из статьи, потом вспомню, какой. AA)
Блокиpовка на всю таблицу пpи UPDATE ставится только в том случае,
если по пpедикату нет индекса. Так, можно пpосто пpоиндексиpовать таблицу orders по
полю customer_id, и не забывать делать UPDATE STATISTIC, хотя
будет работать и с PAGLOCK. Просто не факт, что UPDATE
всегда делает табличную блокировку.
Igor Lemeshko
igor@amanat.alma-ata.su
Q>:
[DESK] Какие есть рекомендации по использованию Apollo SDE?
A>:
1. При работе с Аполло (если у тебя базки в используются и досовскими
задачами) - то в dbgrid'e поставь значение Font->Charset = OEM_Charset.
И не забудь сразу после открытия базы вызывать метод
Apollo1.SetTranslate(True). Если твое приложение будет работать с базами
одновременно с досовскими, то советую перед открытием баз вызывать
метод Apollo1.SysProp( SDE_SP_SETOBUFFER, Pointer(0)) для отключения
буферизации операций чтения/записи в базы.
2.Если ты пишешь приложение, которое будет использовать базы только в
кодировке Windows (CP1251), то тебе достаточно будет указать в dbgrid'e
значение Font->Charset = Russian_Charset.
Roman Procopovich
(2:5030/254.201)
Если базы в 866 кодиpовке, то:
1. Использование TTable + TApollo:
=== Cut ====
TTable.Open;
TApollo.SetTranslate(True);
TTable.Refresh;
=== Cut ====
2. Использование TApTable:
=== Cut ====
TApTable.Open;
TApTable.SetTranslate(True);
TApTable.Refresh;
=== Cut ====
И вместо закоpючек бyдyт pодные pyсские бyквы. Пpавда, только пpи выполнении
пpогpаммы. В дизайнеpе на этапе пpоектиpования псевдогpафика так и останется.
Alexey Kogan
(2:5064/5.30)
Q>:
[VCL] Подскажите как правильно показать на экpане и сохранить в базе
картинку формата JPEG?
A>:
Я делал так (это кусок компонента):
if Picture.Graphic is TJPegImage then
begin
bs:=TBlobStream.Create(TBlobField(Field),bmWrite);
Picture.Graphic.SaveToStream(bs);
bs.Free;
end
else if Picture.Graphic is TBitmap then
begin
Jpg:=TJPegImage.Create;
Jpg.CompressionQuality:=...;
Jpg.PixelFormat:=...;
Jpg.Assign(Picture.Graphic);
Jpg.JPEGNeeded;
bs:=TBlobStream.Create(TBlobField(Field),bmWrite);
Jpg.SaveToStream(bs);
bs.Free;
Jpg.Free;
end else Field.Clear;
Alex Gorbunov
wwwmedia-press.donetsk.ua
(2:465/85.4)
Q>:
[MSSQL] При использовании MS SQL Server 6.5 в NT Performance Monitor
исчезли все датчики, кроме SQL. Как лечить?
A>
Кто виноват:
Дело в следующем - при инсталляции NT страна была поставлена US, затем сменена
на Russia. В реестре для Perfomance Monitor существует (может существовать)
сколь угодно подуровней с названием счетчиков и описанием к ним. При
инсталляции
все естестественно ставилось в ветвь 409 (US) а ветви 419 (Russia) просто не
было. Потом default location была сделана Russia. Perfomance Monitor не мог
найти 419 и брал все счетчики из 409. Но тут пришел SQL и как умная программа
при инсталляции создал ветвь 419 и запихал туда свои счетчики. Теперь
Perfomance
Monitor видит что текущая locale 419, в реестре она есть и берет оттуда
счетчики, а они там только для SQL естественно
Что делать:
Запускаешь regedit (regedt32), находишь где лежат описания счетчиков. Точно я
не помню, под рукой NT нет, но примерно так
HKEY_LOCAL_MACHINE/System/CurrentControlSet/Control/PerfLib/409
(419)
В каждом разделе по два ключа - список названий счетчиков и список их описаний.
Заходишь в 409, открываешь ключ для изменений и при помощи Ctrl-Ins копируешь
его содержимое в буфер обмена и жмешь Cancel. Теперь идешь в 419 открываешь тот
же ключ, идешь в начало списка и при помощи Shift-Ins вставляешь, жмешь Ok.
Так надо сделать и для названий счетчиков и для их описания.
Для полного счастья можно и SQL счетчики из 419 в 409 (в конец) скопировать.
Dmitry Lubimkov
(2:5038/7.26)
Q>:
[BDE] Каковы текущие ограничения BDE?
A>:
BDE: под Windows, все версии.
Если Вы обнаружите, что Вы ограничены более строго, чем здесь описано, или Вы получаете
ошибку выхода за пределы доступной памяти, то увеличение параметра SHAREDMEMSIZE в BDE Config
до 4096 или более может способствовать снятию более строгих ограничений.
Здесь указаны максимальные ограничения для некоторых общих обьектов BDE.
Основные ограничения BDE:
48 клиентов в системе;
32 сессии на одного клиента (для версии 3.5 и ниже, 16 Bit, 32 Bit)
256 сессий на одного клиента (для версии 4.0 и выше, 32 Bit)
32 открытых баз данных на сессию (для версии 3.5 и ниже, 16 Bit, 32 Bit)
2048 открытых баз данных на сессию (для версии 4.0 и выше, 32 Bit)
32 загруженных драйвера
64 сессии в системе (для версии 3.5 и ниже, 16 Bit, 32 Bit)
12288 сессии в системе (для версии 4.0 и выше, 32 Bit)
4000 курсоров на сессию
16 вхождений в стеке ошибок
8 типов таблиц на один драйвер
16 типов полей на один драйвер
8 типов индексов на один драйвер
48K Размер конфигурационного файла (IDAPI.CFG)
64K Максимальный размер оператора SQL при RequestLive=False
4K Максимальный размер оператора SQL при RequestLive=True (для версии 4.0 и ниже, 16/32 Bit)
6K Максимальный размер оператора SQL при RequestLive=True (для версии 4.01 и выше, 32 Bit)
16K Размер буфера записи (SQL и ODBC)
31 Размер имени таблицы и имени поля в символах
64 Размер имени хранимой процедуры в символах
16 Полей в ключе
3 Размер расширения имени файла в символах
260 Длина имени таблицы в символах (некоторые сервера могут иметь другие ограничения)
260 Длина полного имени файла и пути файловой системы в символах
Ограничения Paradox:
127 открытых таблиц в системе (для версии 4.0 и ниже, 16/32 Bit)
254 открытых таблиц в системе (для версии 4.01 и выше, 32 Bit)
64 блокировки на запись на одну таблицу (16Bit) на одну сессию
255 блокировок на запись на одну таблицу (32Bit) на одну сессию
255 записей, учавствующих в транзакции на таблицу (32 Bit)
512 открытых физически файлов (DB, PX, MB, X??, Y??, VAL, TV) (для версии 4.0 и ниже, 16/32 Bit)
1024 открытых физически файлов (DB, PX, MB, X??, Y??, VAL, TV) (для версии 4.01 и выше, 32 Bit)
300 пользователей в одном файле PDOXUSRS.NET
255 полей в таблице
255 размер символьных полей
2 миллиарда записей в таблице
2 миллиарда байт в .DB (таблица) файле
10800 байт на запись для индексированных таблиц
32750 байт на запись для неиндексированных таблиц
127 вторичных индексов на таблицу
16 полей на индекс
255 одновременно работающих пользователей на таблицу
256 Мегабайт данных на одно BLOb поле
100 паролей на сессию
15 длина пароля
63 паролей на таблицу
159 полей с проверками корректности (validity check) (32 Bit)
63 поля с проверками корректности (validity check) (16 Bit)
Ограничения dBase:
256 открытых таблиц dBASE на систему (16 Bit)
350 открытых таблиц dBASE на систему (BDE 3.0 - 4.0, 32 Bit)
512 открытых таблиц dBASE на систему (BDE 4.01 и выше, 32 Bit)
100 блокировок на запись на одной таблице dBASE (16 and 32 Bit)
100 записей, учавствующих в транзакции на таблицу (32 Bit)
1 миллиард записей в таблице
2 миллиарда байт в файле .DBF (таблица)
4000 Размер записи в байтах (dBASE 4)
32767 Размер записи в байтах (dBASE for Windows)
255 Количество полей в таблице (dBASE 4)
1024 Количество полей в таблице (dBASE for Windows)
47 Количество тэгов индексов на один .MDX-файл.
254 Размер символьных полей
10 открытых основных индексов (.MDX) на таблицу
220 Длина ключевого выражения в символах
Borland BDE TI2751 - Some current internal limits of BDE
(перевод: Акжан Абдулин)
> --- added in v4
Q>:
(Oracle) Как при вводе информации в БД автоматически вставлять SEQUENCE?
A>:
Если добавление через оператор insert ( в TQuery), то прямо там пишешь,
как в плюсе ( "... Values (My_seq.nextval,...")
Если добавление идет через TQuery c RequestLive=true, то в PreInsert
сделай запрос через Tquery ( select myseq.nextval from dual) и заноси
значение в свое поле.
Alexander Medvedev
(2:5010/3.88)
Q>:
(SAW) Как правильно работать с SQLAnywhere через BDE -> ODBC -> SAW?
A>:
1) Необходимо поставить patch на ODBC-драйвер (доступен на wwwsybase.com);
2) Достаточно флажка Keys in SQL Statistics в ODBC администpатоpе, для того,
чтобы исчезла необходимость ставить втоpичные индексы по ключевым полям;
3) Если Вы пользуетесь BDE 3.5, то обновите ее до версии 4.x, или замените
idodbc.dll на тот, который идет в комплекте поставки BDE 3.0.
Oleg Saladaev
(2:5015/51.6)