![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Непонятно в Local SQL [D5, dBase, FoxPro]
Евгений Р. © (2007-01-09 23:54:00)Есть запрос:
select rs.opr2,rs.nomer,rs.data1,rs.data2,rs.kolich, sb.mest
from RschBn rs
left join svBn sv
on sv.opr1=rs.opr1
left join StrBn sb
on sb.opr2=rs.opr2
where ((rs.data1<=:data2 and rs.data2>=:data1)
or sv.DataR between :data1 and :data2) and
rs.kGrup=1 and sv.KodStatus=11
Если период (data1 и Data2) достаточно большой (отбирается много записей), то при выполнении выдается ошибка: access violation ... . При меньшем периоде - все работает.
Если в конце первой строки вместо "sb.mest" указать "sb.*", то все замечательно работает при любом периоде.
Таблицы - *.dbf
sniknik (2007-01-11 01:27:00) [1]+
в самих "ключевых" полях зачастую концевики у значений символом "_", опасный символ... ;), это в запросах с LIKE означает любой символ, а как его обрабатывает ленгдрайвер в нестандартной ситуации? хз.
к тому же это явно результат некорректного переноса с какойто системы... в оригинале их наверняка не было (имхо), а при переносе ими "добили" короткие varchar-ы, до максимального размера поля. (заметь они длинной строго 10 даже там где это не нужно, ну не считая пустышек от явных глюков записи)
sniknik (2007-01-11 01:09:00) [2]> Но самое странное - почему работает при sb.*?????
наверное не анализирует по полям, открывает как бы таблицей.
попытайся всеже сделать корректировку структуры/данных (последний абзац в [17]), + вообще наведи порядок в таблице, там у тебя например куча логических полей (у которых в принципе Null нету) не заполнено.
пустышки опять же.
потом связка(обьеденение) по строковым полям тоже какаято... ;(, не нравится мне чегото, на числа нельзя перейти? (потому как это первые поля по которым заподозрил ленгдрайвер... а уж после того как пытался посчитать повторения и сделал группировку по одному из них и SQL Explorer выдал ошибку индекса or ланпдравера... ну понятно)
> А из СУБД, рекомендовал бы FB или MS SQL?
мне практически все равно, но на работе у нас больше востребован MS SQL поэтому им больше и занимаюсь. (под IB 6.5 заказ был 1 единственный раз в 5 лет...)
имхо, что угодно, лиш бы не BDE. :)
Германн (2007-01-11 00:54:00) [3]
> sniknik © (10.01.07 22:48) [18]
>
> > кстати неплохо былобы создать таблицу заново
> а еще лучше забросить BDE совсем, и заняться базами данных.
> .. ;о))
>
Лучше было бы и не начинать с ней шаманские пляски. Но если он только начал, тогда ещё может быть и не поздно.
Евгений Р. (2007-01-11 00:49:00) [4]
> если поменять на DBWINUS0 то начинают отрабатывать оба запроса
Действительно помогло, но ...
Захожу через DataBaseDeskTop. Показывает драйвер Ansi2. Наверное он DBWINUS0 не знает, ставит стандартный. Меняю на 866 - снова глючит. Возвращаю Анси-нормально.
Но у меня там есть русские поля (fio,strana). Они, увы, анси не признают.
Пробовал удалять записи из strBn. Ошибка исчезает только когда удаляется определенное количество записей именно входящих в выборку. Удаление даже всех не входящих ничего не дает.
Но самое странное - почему работает при sb.*?????
Удаление и перезапись тоже не помогают, как и удаление индекса.
> а еще лучше забросить BDE совсем, и заняться базами данных.
> ..
а еще лучше забросить программирование и занятся добычей нефти. Но не всегда выходит делать то, что лучше.
А из СУБД, рекомендовал бы FB или MS SQL?
sniknik (2007-01-10 22:56:00) [5]> открыть таблицей (вернее закрыть таблицу, просто должно быть настроено, от нее "пляшем") и выполнить
> Table1.Close;
oops... это в программе я от нее "пляшу", т.к. она открыта из введенного в эдит, а сам ChangeLangDriver ни с чем не связан... не помню ничего уже ;(
ну да сам разберешься. вроде несложно. по именам параметров понять чего туда нужно. :)
sniknik (2007-01-10 22:48:00) [6]> кстати неплохо былобы создать таблицу заново
а еще лучше забросить BDE совсем, и заняться базами данных... ;о))
sniknik (2007-01-10 22:45:00) [7]да получил, гдето через полчаса после поста...
ошибка в данных всетаки есть, jet не хочет открывать таблицу strBN.DBF если в ней есть 11997-я запись с начала... что в ней такого так и не понял,
зато BDE открывает, ну и ладно (чуток по разному ведут себя и не только в этом).
потом есть 6 пустых записей, т.е. даже индексные (opr1/2) там где пустышки ну никак не уперлись полностью пусты... явно были сбои при записи в таблицу.
по топику, сама с BDE проблема/глюк похоже в ленгдрайвере, если поменять на DBWINUS0 то начинают отрабатывать оба запроса (только не спрашивай как мне в голову пришло проверить ;о)), сам не пойму)
изменить можно так
открыть таблицей (вернее закрыть таблицу, просто должно быть настроено, от нее "пляшем") и выполнить
Table1.Close;
ChangeLangDriver(ExtractFilePath(Edit1.Text), ExtractFileName(Edit1.Text), 'DBWINUS0');
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;
в общемто и все, после этого твоя тестовая програмка уже ошибок не давала.
на всякий случай уже исправленный файл strBN.DBF вместе с програмкой которой можно поменять ленгдрайвер (показанный код из нее).
http://webfile.ru/1275296
пробуй.
кстати неплохо былобы создать таблицу заново и перенести данные в нее (сделать цикл попозаписно, пополям) мало ли чего еще порушено.
(но с ленгдрайвером это не поможет скорее всего, там сами данные влияют, хотя... если эти влияющие данные-"абракадабра" от сбоя, хотя бы от одного символа, и он уберется... то поможет)
Евгений Р. (2007-01-10 21:23:00) [8]Отправил по почте еще 2 раза
Ссылку ввести не получается, наверное рубят.
sniknik (2007-01-10 20:24:00) [9]> Качай по ссылке
по какой? не вижу никакой ссылки, если ты ее письмом выслал то не дошла, возможно спамофильтры "зарубили".
кстати оговорился, нужна не одна таблица а три... по которым запрос строится + индексные/мемо файлы от этих таблиц, т.е. минимум, но достаточно чтобы повторился глюк. а то надо будет индексы переделать, переделаю а глюк в них...
желательно чтобы я сам вообще ничего для воссоздания глюка не делал. а та сделаю "неправильно" ;).
Евгений Р. (2007-01-10 19:39:00) [10]Качай по ссылке
sniknik (2007-01-10 18:11:00) [11]вышли таблицу вместе с этим примером, домой доеду посмотрю.
Евгений Р. (2007-01-10 16:12:00) [12]
> BDE позволяет одноименные, оно с ними "дружит" и понимает
Оба параметра передаются в запрос без проблем. Отчет работает стабильно у многих клиентов и часто используется.
> Вполне возможна порча данных в поле. И при "небольшом диапазоне
> дат" просто эта порченая запись не выбирается.
> Встречал такое. Особенно, если происхождение эти DBF - неизвестная
> ДОС-программа.
Данные созданы только этой программой через это БДЕ.
Если диапазон проходить по кускам - все нормально для каждого участка. Если целиком - ошибка.
Если из таблицы выбрано одно поле - ошибка, если все - нормально?????
Евгений Р. (2007-01-10 16:07:00) [13]
> то не сложно привести его целиком. Не помню только, когда
> dfm стали текстовыми :( В Д5 или в Д6?
unit qqqq;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, DBTables, StdCtrls, Grids, DBGrids;
type
TForm1 = class(TForm)
qu: TQuery;
Button1: TButton;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
qu.ParamByName('data1').asDateTime:=encodeDate(2006,01,1);
qu.ParamByName('data2').asDateTime:=encodeDate(2006,12,31);
showMessage('Перед');
qu.open;
showMessage('После');
end;
end.
*****************************************
object Form1: TForm1
Left = 192
Top = 107
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 288
Top = 40
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object DBGrid1: TDBGrid
Left = 48
Top = 168
Width = 625
Height = 201
DataSource = DataSource1
TabOrder = 1
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
end
object qu: TQuery
DatabaseName = 'DebugVest'
SQL.Strings = (
'select rs.opr2,rs.nomer,rs.data1,rs.data2,rs.kolich,sb.*'
'from RschBn rs'
'left join svBn sv'
' on sv.opr1=rs.opr1'
'left join StrBn sb'
' on sb.opr2=rs.opr2'
'where ((rs.data1<=:data2 and rs.data2>=:data1)'
' or sv.DataR between :data1 and :d' +
'ata2) and'
' rs.kGrup=1 and sv.KodStatus=11'
'')
Left = 128
Top = 64
ParamData = <
item
DataType = ftUnknown
Name = 'data2'
ParamType = ptUnknown
end
item
DataType = ftUnknown
Name = 'data1'
ParamType = ptUnknown
end
item
DataType = ftUnknown
Name = 'data1'
ParamType = ptUnknown
end
item
DataType = ftUnknown
Name = 'data2'
ParamType = ptUnknown
end>
end
object DataSource1: TDataSource
DataSet = qu
Left = 192
Top = 64
end
end
sniknik (2007-01-10 12:57:00) [14]> Что-то не припомню такого, как раз наоборот честный, одно значение - один плейсхолдер.
проверял так, как раз после случая на форуме когда уверяли, что работает, а по идее изза задвоенных имен параметров не должно, так то я с BDE практически не работал, бог миловал ;), сразу в дельфи на ADO начал.
procedure TForm1.Button1Click(Sender: TObject);
begin
Query1.SQL.Text:= 'SELECT ID, :ParAS Param FROM Test.Dbf WHERE ID= :Par'; //2!
Query1.ParamByName('ID').AsInteger:= 81; //1 раз!
Query1.Open;
end;
после выполнения было 2 столбца одинаковых цифр. из чего сделал вывод, значения от единственного присвоения получили оба параметра и тот что "AS Param" и в условии, т.к. и условие сработало (выборка 1 значения цифры из множества) и в подстановке нормальное значение есть.
если это означает чтото другое... ну я не знаю тогда что. проверьте сами.
а вот каким образом получили, на уровне движка, или парсер в разборе "умный" делает ссылки на значение, или еще как, не разбирался. да и не нужно мне это. (BDE для меня не рабочий инструмент, а так, иногда развлечься ;о))
Anatoly Podgoretsky (2007-01-10 12:30:00) [15]> sniknik (10.01.2007 00:50:04) [4]
> BDE позволяет одноименные, оно с ними "дружит" и понимает ;).
Что-то не припомню такого, как раз наоборот честный, одно значение - один плейсхолдер.
Desdechado (2007-01-10 11:21:00) [16]Вполне возможна порча данных в поле. И при "небольшом диапазоне дат" просто эта порченая запись не выбирается.
Встречал такое. Особенно, если происхождение эти DBF - неизвестная ДОС-программа.
Германн (2007-01-10 02:08:00) [17]
> Для проверки сделал новое приложение с одной формой. В кнопке
> код:
> qu...
А что есть qu?
Если сделал тестовое приложение
> с одной формой.
, то не сложно привести его целиком. Не помню только, когда dfm стали текстовыми :( В Д5 или в Д6?
Евгений Р. (2007-01-10 01:32:00) [18]Структура sb:
strBN.DBF 31909 31909
OPR1 C10/11 TStringField
OPR2 C10/11 TStringField
NRASP N / 8 TFloatField
KODORG N / 8 TFloatField
NOMER N / 2 TSmallintField
PBRN L / 2 TBooleanField
PRNZ L / 2 TBooleanField
RNZ N / 2 TSmallintField
PBEZPODS L / 2 TBooleanField
PDOPMEST L / 2 TBooleanField
PSTRAXOVKI L / 2 TBooleanField
VDTRF N / 2 TSmallintField
STRANA C20/21 TStringField
TIPPROG N / 2 TSmallintField
FIO C25/26 TStringField
POL N / 2 TSmallintField
DATA1 D / 4 TDateField
TIME1 N / 8 TFloatField
DATA2 D / 4 TDateField
TIME2 N / 8 TFloatField
PROGITO N / 8 TFloatField
TARIF N / 8 TFloatField
PPERESEL L / 2 TBooleanField
MEST N / 2 TSmallintField
Ошибку дает именно запрос. Для проверки сделал новое приложение с одной формой. В кнопке код:
qu.ParamByName('data1').asDateTime:=encodeDate(2006,01,1);
qu.ParamByName('data2').asDateTime:=encodeDate(2006,12,31);
showMessage('Перед');
qu.open;
showMessage('После');
Окошко с первой надписью показывает, со второй - нет.
То же в отладчике.
Германн (2007-01-10 01:00:00) [19]
> ошибка для запроса больно странная, не в нем происходит,
> имхо.
>
Угу. Более вероятно, что ошибка в коде, в котором используются результаты запроса. Очень интересно что ещё есть в таблице sb, кроме
> mest
?
sniknik (2007-01-10 00:50:00) [20]> В запросе 4 параметра data2, data1, data1 и data2
BDE позволяет одноименные, оно с ними "дружит" и понимает ;).
нет, сдесь чтото другое, но что х.з. ошибка для запроса больно странная, не в нем происходит, имхо.