Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

BDE. Ошибка с SQL и уникальным индексом [D5, D7, Paradox]


Страницы:   1 2

-=Guest=- ©   (2003-05-05 21:24:00) 

Есть таблица Paradox.
Поля ID, ID1, ID2 - все Long Integer
ID - первичный ключ.
По полям ID1 и ID2 есть уникальный индекс.

Добавляю значения 1,1,1
Затем используя TTable пытаюсь добавить 2,1,1 - естественно "Key violuation"

Но беру TQuery и делаю "Insert Into "MyTable.db" Values(2,1,1)"

Добавило !!!

После этого и TTable и TQuery может вводить любые дублирующиеся записи(типа 3,1,1 4,1,1 и т.д.), а если сделать переиндыксацию таблицы - то мой уникальный индекс вообще удаляется, как будто его и не было.

Проверил на трех машинах Win98-D5 и WinXp-D7

Для работы с таблицей использовал Database Explorer(из RxLib Demo) и SQL Explorer из Delphi.
Таблица создавалась в Database Desktop.


Dred2k   (2003-05-07 11:49:00) [1]


> NikB (07.05.03 11:33)

DbiOpenCfgInfoList. В bde32.hlp есть подробное описание и примеры. Получить значения для анализа можно также через Session.GetConfigParams.


Verg   (2003-05-07 11:46:00) [2]

Вот процедура установки параметра


procedure SetConfigParameter(Param: string; Value: string);
var
hCfg: hDBICfg;
Config: SYSConfig;
Path, Option: string;
ParamCount, I: word;
pFields, pFld: pFLDDesc;
pRecBuf, pRec: pBYTE;
Found, SelfInitialized: boolean;
rslt: DBIResult;

begin

{$Ifdef WIN32}
hCfg := nil; pFld := nil; pRec := nil; Found := False; SelfInitialized := False;
try
if Pos(";", Param) = 0 then
raise EDatabaseError.Create("Invalid parameter passed to function. There must " +
"be a semi-colon delimited sting passed");
Path := Copy(Param, 0, Pos(";", Param) - 1);
Option := Copy(Param, Pos(";", Param) + 1, Length(Param) - Pos(";", Param));

rslt := DbiGetSysConfig(Config);
if rslt <> DBIERR_NONE then
begin
if rslt = DBIERR_NOTINITIALIZED then // Engine not initialized error...
begin
SelfInitialized := True;
DbiInit(nil);
Check(DbiGetSysConfig(Config));
end
else
Check(rslt);
end;
(* DbiOpenConfigFile is defined as such:
function DbiOpenConfigFile ( { Open/Create configuration }
pszDirPath : PChar; { Directory }
bCreate : Bool; { TRUE to create/overwrite }
var hCfg : hDBICfg { Handle to config }
): DBIResult stdcall; *)
Check(DbiOpenConfigFile(Config.szIniFile, FALSE, hCfg));

(* DbiCfgGetRecord is defined as such:
function DbiCfgGetRecord ( { Get a record }
hCfg : hDBICfg; { Config Handle/NULL }
pszCfgPath : PChar; { Path }
var iFields : Word; { Returned nbr of fields }
pfldDesc : pFLDDesc; { Field descriptors }
pRec : Pointer { Field values }
): DBIResult stdcall; *)
{ Call it without the field and record buffer to get the count... }
Check(DbiCfgGetRecord(hCfg, PChar(Path), ParamCount, nil, nil));

pFields := AllocMem(ParamCount * sizeof(FLDDesc));
pFld := pFields;
pRecBuf := AllocMem(10000);
pRec := pRecBuf;

{ Get the node values... }
Check(DbiCfgGetRecord(hCfg, PChar(Path), ParamCount, pFields, pRecBuf));

for I := 0 to ParamCount - 1 do
begin
if pFields^.szName = Option then
begin
StrPCopy(PChar(pRecBuf), Value);

(* DbiCfgModifyRecord is defines as such:
function DbiCfgModifyRecord ( { Modify a record }
hCfg : hDBICfg; { Config Handle/NULL }
pszCfgPath : PChar; { Path }
iFields : Word; { Nbr of fields }
pfldDesc : pFLDDesc; { Field descriptors }
pRec : Pointer { Data values }
): DBIResult stdcall; *)
Check(DbiCfgModifyRecord(hCfg, PChar(Path), ParamCount, pFld, pRec));

Found := True;
end;
Inc(pFields);
Inc(pRecBuf, 128);
end;
if Found = False then
raise EDatabaseError.Create(Param + " entry was not found in configuration file");

finally
if pFld <> nil then
FreeMem(pFld);
if pRec <> nil then
FreeMem(pRec);
if hCfg <> nil then

(* DbiCloseConfigFile is defined as such:
function DbiCloseConfigFile ( { Close the config file }
var hCfg : hDBICfg; { Handle }
bSave : Bool; { To save the changes }
bDefault : Bool; { To make this file the default }
bSaveAs16 : Bool { To save as a 16-bit config file }
): DBIResult stdcall; *)
{ Close and save the config file... }
Check(DbiCloseConfigFile(hCfg, TRUE, TRUE, FALSE));
if SelfInitialized = True then
DbiExit;
end;
{$Else}
raise EDatabaseError.Create("Non supported function in 16 bit");
{$EndIf}
end;


Verg   (2003-05-07 11:41:00) [3]

Так проверить (извини, куски кода)

uses Windows,BDE, SysUtils;

const
{ System Initialization Settings... }
bcfgAUTOODBC = "\SYSTEM\INIT\;AUTO ODBC";
bcfgDATAREPOSITORY = "\SYSTEM\INIT\;DATA REPOSITORY";
bcfgDEFAULTDRIVER = "\SYSTEM\INIT\;DEFAULT DRIVER";
bcfgLANGDRIVER = "\SYSTEM\INIT\;LANGDRIVER";
bcfgLOCALSHARE = "\SYSTEM\INIT\;LOCAL SHARE";bcfgLOWMEMORYUSAGELIMIT = "\SYSTEM\INIT\;LOW MEMORY USAGE LIMIT";
bcfgMAXBUFSIZE = "\SYSTEM\INIT\;MAXBUFSIZE";
bcfgMAXFILEHANDLES = "\SYSTEM\INIT\;MAXFILEHANDLES";
bcfgMEMSIZE = "\SYSTEM\INIT\;MEMSIZE";
bcfgMINBUFSIZE = "\SYSTEM\INIT\;MINBUFSIZE";
bcfgSHAREDMEMLOCATION = "\SYSTEM\INIT\;SHAREDMEMLOCATION";
bcfgSHAREDMEMSIZE = "\SYSTEM\INIT\;SHAREDMEMSIZE";
bcfgSQLQRYMODE = "\SYSTEM\INIT\;SQLQRYMODE";
bcfgSYSFLAGS = "\SYSTEM\INIT\;SYSFLAGS";
bcfgVERSION = "\SYSTEM\INIT\;VERSION";

function GetConfigParameter(Param: string; Count: pword): string;
var
hCur: hDBICur;
rslt: DBIResult;
Config: CFGDesc;
Path, Option: string;
Temp: array[0..255] of char;

begin
Result := ""; hCur := nil;
if Count<>nil then
Count^ := 0;
try
if Pos(";", Param) = 0 then
raise EDatabaseError.Create("Invalid parameter passed to function. There must " +
"be a semi-colon delimited sting passed");
Path := Copy(Param, 0, Pos(";", Param) - 1);
Option := Copy(Param, Pos(";", Param) + 1, Length(Param) - Pos(";", Param));
Check(DbiOpenCfgInfoList(nil, dbiREADONLY, cfgPERSISTENT, StrPCopy(Temp, Path), hCur));
Check(DbiSetToBegin(hCur));
repeat
rslt := DbiGetNextRecord(hCur, dbiNOLOCK, @Config, nil);
if rslt = DBIERR_NONE then
begin
if StrPas(Config.szNodeName) = Option then
Result := Config.szValue;
if Count <> nil then
Inc(Count^);
end
else
if rslt<>DBIERR_EOF then
Check(rslt);
until rslt <> DBIERR_NONE;
finally
if hCur <> nil then
Check(DbiCloseCursor(hCur));
end;
end;


if GetConfigParameter(bcfgLOCALSHARE,nil)<>"TRUE" then <Нет LocalShare>


NikB   (2003-05-07 11:33:00) [4]

Izvinite, chto v etoi vetvi stavliu vopros.
Kak mojno programno (D5) proverit i izmenit "LocalShare" BDE?


Валерий   (2003-05-07 04:25:00) [5]

>Guest
Но беру TQuery и делаю "Insert Into "MyTable.db" Values(2,1,1)"

Я тоже попробовал этот запрос в SQL Explorer из Delphi
у меня выдало ошибку кеу violation indid2
но после какого-то запроса перестало выдавать ошибку
Налицо глюк!


Mike Kouzmine   (2003-05-06 16:08:00) [6]

Я сейчас пробовал это описанное, у меня все окейно. Аксес не смог вставить. DBD не смог вставить.
Как мне кажеться, Dred не так уж неправ. И с val и с индексами.


Dred2k   (2003-05-06 15:58:00) [7]


> Verg © (06.05.03 15:47)

Да вот, я без нее тоже никуда - аж, порой, забываешь о ее существовании. ;))


Verg   (2003-05-06 15:47:00) [8]


> LocalShare нужет для The ability to share .....


Не только, хоть и написано help-e, но замечено: сам Borland давным-давно давал как "рецепт от многих болезней" - установка LocalShare=true. Помнится впервые этот совет последовал от Борланда при лечении "Blob has been modifyed"...
Ну с тех пор я нераздумывая, всегда это "локалшару" ставлю - как рефлекс : "увидел paradox - поставь локалшару" :)))


Dred2k   (2003-05-06 15:07:00) [9]


> MsGuns © (06.05.03 14:40)

Мда... Клоаку прорвало...


MsGuns   (2003-05-06 14:40:00) [10]

>Dred2k © (06.05.03 14:30)
>С файлом .val разберись, прежде чем психоанализом заниматься. Мастер! ;))

Достал пацан 8([]) Где ты увидел хоть раз что я хоть каким нибудь косвенным образом присвоил себе это звание ? Кто тебе вдолбал в твою очень умную (как тебе кажется) голову, что я не знаю с чем едят val ? Когда и кто дал тебе право относиться заносчиво и даже хамски к кому бы-то ни было, в т.ч. и на форуме ? Какой негодяй в какой сволочной школе научил тебя начинать спор со слов "бред", "чушь" и т.д. ? Почему вместо нормального аргументированного опровержения мнения оппонента ты переходишь на издевки и оскорбления ? Кто ты такой ? Гусь хрустальный ? Орел степной ? Или хамло обыкновенное ?

А анкета у тебя соответствующая. Чтоб, тявкнув, можно было свалить в любой момент и концы в воду.

На сем прощаюсь с тобой. Без малейшего уважения.



Dred2k   (2003-05-06 14:30:00) [11]


> MsGuns © (06.05.03 14:10)

С файлом .val разберись, прежде чем психоанализом заниматься. Мастер! ;))


MsGuns   (2003-05-06 14:10:00) [12]

>Dred2k © (06.05.03 12:54)

Вникать с смысл высказанного оппонентом мы не желаем, выдаем кажущееся за действительное, при этом упиваемся собственным умищем, знанищем и опытищем, по ходу дела свысока поплевывая на вертящихся вокруг недотеп, включая автора сабжа ;))

Ну-ну !!


Dred2k   (2003-05-06 12:54:00) [13]


> MsGuns © (06.05.03 12:38)

Поздравляю, маэстро.
Файлы .val - validity checks, понятия "активный/неактивный индекс" в парадоксе нет - индексы бывают maintained (автообновляемые) и не-... Все уникальные (как в вопросе) - maintained. В DBD указать индекс "по умолчанию" просто нельзя за отсутствием такового понятия. К файлам .val вообще какая-то страсть, что ли... ;)
LocalShare нужет для The ability to share access to local data between an active BDE application and an active non-BDE application. Set to TRUE if you need to work with the same files through both a BDE and a non-BDE application at the same time. (It is not necessary to set LOCAL SHARE to TRUE if you do not need to have both applications open at the same time.) Default: FALSE.

> -=Guest=- (06.05.03 12:21)

Насчет квалификаций "объяснений" палку не перегибай - ты тоже тут сотрясал воздух часами за компом, осями, дельфями и проведенными выходными... Мои "сервера" тебе в пику были, чтоб не скучно. ;)


MsGuns   (2003-05-06 12:41:00) [14]

Поправка дабы еще раз не обвинили в софистике ;)
Фраза Еще раз повторю, что индексы в Парадоксе - это не Constraints в SQL-серверах, а лишь их имитация НА КЛИЕНТЕ.относится, ессно не вообще к индексам, а лишь к поддержке их уникальности.




MsGuns   (2003-05-06 12:38:00) [15]

>Dred2k © (05.05.03 23:03)
>MsGuns кудряво так все описал, что я куплю себе учебник по софистике... Для начинающего.

Для начала ничего покупать не надо, а просто внимательно почитать о BDE и вдуматься в то, а нафига нужны парадоксу (но не самому BDE как таковому) файлы .val и разобраться с понятиями "Индекс" и "Активный индекс"

>Verg © (06.05.03 08:58)
>Никогда такого не бывало, чтобы уникальные индексы дублировались.
Если id1 и id2 образуют составной уникальный индекс,названный, например, id12, то при выполнении SQL вносящего неуникальные значения в id1,id2 через самый обныкновенный TQuery без всякого там requestLive возникает исключение Key Violation. Index ID12.
Я только что попробовал это на D4 BDE 5.0.1.22 localhare=true

Это потому, что данный индекс активен (возможно, указан по умолчанию в DBD - проверь, есть ли файл .val ?). Или узер (приложение) делает всю таблицу "сразу обновляющейся" (LocalShare=true) и тогда все действующие ограничения (в т.ч. и уникальность индекса) становятся актуальными для ЛЮБЫХ запросов к этой таблице.
Еще раз повторю, что индексы в Парадоксе - это не Constraints в SQL-серверах, а лишь их имитация НА КЛИЕНТЕ.




-=Guest=-   (2003-05-06 12:21:00) [16]

Уважаемые Господа, спасибо за Ваши ответы.

У меня ошибка действительно существует, но испавляется это с помощью localhare=true;

После этого все заработало как положенно.
Но если снова установить localhare=false - появляется ошибка, описанная выше

Документацию на BDE почитал.
Возможно, как утверждал MsGuns ©, в этом случае
"Для запроса BDE держит кэш активных индексов " (MsGuns © (05.05.03 21:45)). Это объянение подходит лучше, чем "пары сервачков ... и десятки тыщ записей"(Dred2k © (05.05.03 23:46))

Параметр localhare по-умолчанию установлен в false.

Может у кого-нибудь есть желание поэксперементировать, может у меня BDE каличное.


Danilka   (2003-05-06 10:07:00) [17]

Dred2k © (05.05.03 22:35)
>Никаких аргументов далее не будет

Очень жаль что не будет, мне-бы очень было интересно их услышать, т.к. я не вижу ниодного плюса использования парадокса, дбф-ок и т.д., по сравнению с сервером, одни минусы, а уж при использовании в могопользовательских приложениях минусов в виде загруженности сети/клиентов становится на порядки больше.

>Если б было так, то BDE вообще не вышел бы на рынок
Когда была в нем необходимость - он вышел, сейчас он все больше и больше вытесняется с этого рынка. Какая последняя версия БДЕ? Как давно она вышла?

Хотя, этому место в "потрепаться".


VAleksey   (2003-05-06 09:01:00) [18]


> MsGuns © (06.05.03 00:46)

Не так уж он и не прав... Черт, компа нету дома, а то бы я тоже проверил все ваши выкладки.


Verg   (2003-05-06 08:58:00) [19]

Не, на самом деле "орех" прав.
Никогда такого не бывало, чтобы уникальные индексы дублировались.
Если id1 и id2 образуют составной уникальныйиндекс,названный, например, id12, то при выполнении SQL вносящего неуникальные значения в id1,id2 через самый обныкновенный TQuery без всякого там requestLive возникает исключение Key Violation. Index ID12.
Я только что попробовал это на D4 BDE 5.0.1.22 localhare=true

Что-то тут не то. В самом деле, смотреть надо.



MsGuns   (2003-05-06 00:46:00) [20]

>Dred2k

Да, крутой орех ! И, главное, ведь такое впечатление, что сам верит в то, что несет !;))


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо