Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.05;
Скачать: CL | DM;

Вниз

Работа с большим числом   Найти похожие ветки 

 
Andrey V. ©   (2004-02-08 10:29) [0]

Возникла необходимость хранить в базе большое число
(~13 знаков).
В базе создал NUMERIC (15,0), а с интерфейсом запнулся.
Стандартные vclы не подходят.
TSpin подошел бы, но он не может работать с числом больше integer.
TCurrencyEdit (от RX) кажет всякие "E" , что нежелательно.
Пришлось сотановиться на TEdit.
Теперь не могу пинуть его содержимое в базу , ругается ... numeric overflow ...

Ну не хранить же его в текстовом виде ?? (хотя ...)


 
Anatoly Podgoretsky ©   (2004-02-08 12:29) [1]

Грустная история.


 
Andrey V. ©   (2004-02-08 14:35) [2]

От человека такого уровня , это воспринимается как приговор :-)
И все же ?


 
Anatoly Podgoretsky ©   (2004-02-08 14:45) [3]

Что все же, ну рассказал ты грустную историю, а что дальше. Конечно лучше ее было в Потрепаться опубликовать, там такие истории любят.


 
KA_ ©   (2004-02-08 16:45) [4]

>Andrey V. © (08.02.04 10:29)
>Ну не хранить же его в текстовом виде ??

А почему нет?
Вот тебе пример модуля - справочника банков:

unit uKisBanks;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uKisClasses, DB, ImgList, ActnList, IBCustomDataSet, IBDatabase,
DBTables, uKisUtils;

type
EInvalidBIK = EAbort;
EInvalidKAccount = EAbort;
EInvalidTown = EAbort;
EInvalidBankGroup = EAbort;
EInvalidName = EAbort;

TKisBank = class(TKisEntity)
private
FBIK: Integer;
FName: String;
FKAccount: String;
FTown: String;
FBankGroup: SmallInt;
procedure CheckBIK(ABIK: Integer);
procedure CheckKAccount(const AKAccount: String);
procedure CheckName(const AName: String);
procedure CheckEditor(Editor: TForm);
procedure SetBIK(const Value: Integer);
procedure SetName(const Value: String);
function BIKString: String;
procedure SetKAccount(const Value: String);
procedure SetTown(const Value: String);
procedure SetBankGroup(const Value: SmallInt);
protected
function GetText: String; override;
public
constructor Create(Mngr: TKisEntityMngr); override;
function Edit: Boolean; override;
property Name: String read FName write SetName;
property BIK: Integer read FBIK write SetBIK;
property KAccount: String read FKAccount write SetKAccount;
property Town: String read FTown write SetTown;
property BankGroup: SmallInt read FBankGroup write SetBankGroup;
end;

TKisBankMngr = class(TKisEntityMngr)
dsSelect: TIBDataSet;
Transaction: TIBTransaction;
dsSelectID: TIntegerField;
dsSelectNAME: TIBStringField;
dsSelectBIK: TIBStringField;
dsSelectK_ACCOUNT: TIBStringField;
dsSelectTOWN: TIBStringField;
dsSelectBANK_GROUP: TSmallintField;
procedure DataModuleCreate(Sender: TObject);
private
{ Private declarations }
protected
procedure CreateView; override;
procedure Activate; override;
procedure Deactivate; override;
public
procedure LoadData; override;
function CurrentEntity: TKisEntity; override;
end;

implementation

{$R *.dfm}

uses
uKisBankEditor, DM;

const
S_INVALID_BIK = "Неверное значение БИК!";
S_INVALID_KACCOUNT = "Неверное значение корр/счета!";
S_INVALID_NAME = "Неверное наименование банка!";
S_EDITOR_NOT_ASSIGNED = "Не найден редактор свойств банка!";

type
TNumberChar = set of Char;

const
NumberChars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];

function CharIsNumber(C: Char): Boolean;
begin
Result := C in NumberChars;
end;

function StrIsNumber(const S: String): Boolean;
var
I: Integer;
begin
Result := True;
for I := 1 to Length(S) do
if not CharIsNumber(S[I]) then
begin
Result := False;
Exit;
end;
end;
{ TKisBank }

function TKisBank.BIKString: String;
begin
Result := Format("%9.9d", [FBIK]);
end;

procedure TKisBank.CheckBIK(ABIK: Integer);
begin
//raise EInvalidBIK.Create(S_INVALID_BIK);
end;

procedure TKisBank.CheckEditor(Editor: TForm);
begin
if Assigned(Editor) then
with Editor as TKisBankEditor do
begin

end
else
raise EAbort.Create(S_EDITOR_NOT_ASSIGNED);
end;

procedure TKisBank.CheckKAccount(const AKAccount: String);
begin
if not StrIsNumber(AKAccount) {or ((Length(AKAccount) <> 18) or
(Length(AKAccount) <> 20))} then
raise EInvalidKAccount.Create(S_INVALID_KACCOUNT);
end;

procedure TKisBank.CheckName(const AName: String);
begin
if Trim(AName) = EmptyStr then
raise EInvalidName.Create(S_INVALID_NAME);
end;

constructor TKisBank.Create(Mngr: TKisEntityMngr);
begin
inherited;
FBankGroup := 0;
end;

function TKisBank.Edit: Boolean;
var
I: Integer;
L: TStringList;
begin
inherited;
with TKisBankEditor.Create(Application) do
begin
edName.Text := Self.FName;
edTown.Text := Self.FTown;
edBIK.Text := IntToStr(FBIK);
edKAccount.Text := FKAccount;
cbStates.Items.Add("неопределен");
L := DModule.GetStatesList;
cbStates.Items.AddStrings(L);
L.Free;
I := cbStates.Items.IndexOfObject(Pointer(Self.FBankGroup));
if I < 0 then I := 0;
cbStates.ItemIndex := I;
Result := ShowModal = mrOK;
if Result then
try
Self.BIK := StrToInt(edBIK.Text);
Self.Name := edName.Text;
Self.Town := edTown.Text;
Self.KAccount := edKAccount.Text;
Self.BankGroup := Integer(cbStates.Items.Objects[cbStates.ItemIndex]);
except
end;
Release;
end;
end;

function TKisBank.GetText: String;
begin
Result := Self.Name + " " + Self.Town + " " + Self.BIKString;
end;

procedure TKisBank.SetBankGroup(const Value: SmallInt);
begin
if FBankGroup <> Value then
begin
FBankGroup := Value;
Modified := True;
end;
end;

procedure TKisBank.SetBIK(const Value: Integer);
begin
CheckBIK(Value);
if FBIK <> Value then
begin
FBIK := Value;
Modified := True;
end;
end;

procedure TKisBank.SetKAccount(const Value: String);
begin
CheckKAccount(Value);
if FKAccount <> Value then
begin
FKAccount := Value;
Modified := True;
end;
end;

procedure TKisBank.SetName(const Value: String);
begin
CheckName(Value);
if FName <> Value then
begin
FName := Value;
Modified := True;
end;
end;

procedure TKisBank.SetTown(const Value: String);
begin
if FTown <> Value then
begin
FTown := Value;
Modified := True;
end;
end;

{ TKisBankMngr }

procedure TKisBankMngr.Activate;
begin
inherited;
if not Transaction.Active then
Transaction.StartTransaction;
LoadData;
end;

procedure TKisBankMngr.CreateView;
begin
inherited;
FView.Caption := "Банки";
end;

procedure TKisBankMngr.Deactivate;
begin
inherited;
if Transaction.Active then
Transaction.Commit;
end;

procedure TKisBankMngr.LoadData;
begin
inherited;
dsSelect.Open;
dsSelect.FetchAll;
end;

procedure TKisBankMngr.DataModuleCreate(Sender: TObject);
begin
inherited;
Transaction.DefaultDatabase := DModule.Database;
dsSelect.Transaction := Transaction;
end;

function TKisBankMngr.CurrentEntity: TKisEntity;
begin
if dsSelect.Active then
begin
Result := TKisBank.Create(Self);
with Result as TKisBank do
begin
ID := dsSelect.FieldByName("ID").AsInteger;
Name := dsSelect.FieldByName("NAME").AsString;
BIK := dsSelect.FieldByName("BIK").AsInteger;
KAccount := dsSelect.FieldByName("K_ACCOUNT").AsString;
Town := dsSelect.FieldByName("TOWN").AsString;
BankGroup := dsSelect.FieldByName("BANK_GROUP").AsInteger;
end;
end
else
Result := nil;
end;

end.


Поле K_ACCOUNT содержит коррсчет банка - 20 символов, все цифры.
При его установке проверка на правильность. С показом вообще проблем нет.


 
KA_ ©   (2004-02-08 16:48) [5]

TKisBankMngr - это TDataModule, который содержит все запросы и пр. средства для работы с БД.


 
Deniz ©   (2004-02-09 09:52) [6]

Ну зачем же так, приговор.
Понятие IB6.x уже достаточно размыто, поэтому надо указывать конкретную версию сервера.
Вот например в FB1.5 есть такой тип данных BIGINT, так вот 18(восемнадцать) 9 туда "залазят" без проблем!


 
Vlad ©   (2004-02-09 10:00) [7]


> Andrey V. © (08.02.04 10:29)


а TDBEdit чем не устраивает ?


 
Anatoly Podgoretsky ©   (2004-02-09 10:09) [8]

Vlad © (09.02.04 10:00) [7]

Читай
Andrey V. © (08.02.04 10:29)
Стандартные vclы не подходят.


 
Vlad ©   (2004-02-09 10:31) [9]


> Anatoly Podgoretsky © (09.02.04 10:09) [8]


> Стандартные vclы не подходят.
> Пришлось сотановиться на TEdit.


Дейсвительно, грусная история... ;-)


 
KA_ ©   (2004-02-09 10:45) [10]

>Vlad © (09.02.04 10:31) [9]
>Дейсвительно, грусная история... ;-)

ИМХО, самый верный вариант. DB-контролы к большому сожалению имеют массу минусов: затягивают транзакции во времени, уменьшают контроль программиста над данными и пр. Стараюсь не использовать их.


 
Anatoly Podgoretsky ©   (2004-02-09 10:48) [11]

Vlad © (09.02.04 10:31) [9]
Только вот почему он свое горе здесь извлекает, а не в потрепаться, этот же форум предназначен для решения вопросов, а не для соболезнований.


 
Vlad ©   (2004-02-09 10:49) [12]


> KA_ © (09.02.04 10:45) [10]

Я не об этом. Я о противоречии двух строк из поста автора :-)
То что ты стараешься их не использовать- это твое право, но вот это:


> DB-контролы к большому сожалению имеют массу минусов: затягивают
> транзакции во времени, уменьшают контроль программиста над
> данными и пр.


ИМХО, фигня полная.


 
KA_ ©   (2004-02-09 10:54) [13]

>Vlad © (09.02.04 10:49) [12]
>ИМХО, фигня полная.

Спасибо, отец, утешил.


 
Vlad ©   (2004-02-09 11:08) [14]


> KA_ © (09.02.04 10:54) [13]

Я просто никак в толк не возьму:
1) какое отношение DB-Aware контролы имеют к транзакциям в БД (или поясни, о каких транзакциях идет речь ?)
2) каким это образом TDBEdit может уменьшать контроль над данными по сравнению с TEdit ?


 
KA_ ©   (2004-02-09 11:39) [15]

>Vlad © (09.02.04 11:08) [14]
> 1) какое отношение DB-Aware контролы имеют к транзакциям в БД

Рассмотрим обычную ситауцию - ввод данных. Пока пользователь вводит данные (через DB-контролы) транзакция (созданная дл яввода данных) активна. Это часто приводит к появлению конфликтов с другими пользователями (оператор может долго думать, или пойти покурить, вспомнить о включенном дома утюге и т.д.)
Общее правило построения многопользовательских приложений БД - транзакции должны быть еще короче.
Без использования DB-контролов приходится загонять данные ручками в стандартные контролы. Зато транзакции укорачиваются - запустил транзакцию, прочитал данные, занес в контролы, закрыл. Пользователь может редактировать сколько хочет. Когда захочет сохранить - снова запускаем транзакцию, пишем, закрываем.
Правда такой подход требует бОльших телодвижений.

Я обычно завожу вообще две транзакции - одну только для чтения (обычно она мало нагружает сервер), другую для дабавления/удаления/редактирования. Читающая может быть сколь угодно долгой, а пишущая должна быть короткой.

> 2) каким это образом TDBEdit может уменьшать контроль над данными по сравнению с TEdit

Не всегда данные в БД подчиняются простеньким правилам. При необходимости выполнять сложные проверки DB-контролы связывают по рукам и ногам.

P.S. Повторяю, все написанное - лишь мое личное мнение.


 
Andrey V. ©   (2004-02-09 11:51) [16]

> Стандартные vclы не подходят.
> Пришлось сотановиться на TEdit.

:-)
Я , конечно не так выразился, имелись ввиду компоненты
работающие с числами, их вводом в смысле. Типа Spinа.
DB-Aware я не использую , это уже отдельная тема , и действительно для Потрепаться.
На форме набросаны TEditы и т.п.
Затем , по нажатию кнопки "сохранить" делается что-то типа
UPDATE ... SET SomeField1=:SomeField1
а затем

ParamByName("SomeField1").AsString:=EditSomeField1.Text

Ну и что сдесь такого? Вот так я работаю ... Если я не правильно делаю , так научусь когда-н. и правильно делать (наверно).
Все было хорошо , пока не пришлось ввести ЧИСЛО(большое в смысле)
И со стороны IB как раз проблем нет.
Ну да ладно. Сделал я в итоге текстовое поле , черт с ним.

ЗЫ. Чуствую , я на пол-пути в Потрепаться :-[ ]


 
Vlad ©   (2004-02-09 11:58) [17]


> KA_ © (09.02.04 11:39) [15]

Применительно к IB обычно действительно рекомендуется разделять пишущие и читающие транзакции.
Но. Если пользователь ушел курить или спать или неважно куда, а у него висит окошко с DB-aware контролами это не значит что у него будет висеть пишущая транзакция. Ее не будет до тех пор, пока пользователь не вызовет метод Post или явно не откроет транзакцию.

P.S. Неужели ты вместо DBGrid используешь TStringGrid ? Судя по твоей логике нужно делать именно так...
P.P.S. TDBEdit является наследником того же TCustomEdit, не понимаю как он может связывать по рукам и ногам


 
KA_ ©   (2004-02-09 12:34) [18]

>Vlad © (09.02.04 11:58) [17]
> Применительно к IB
О нем и речь.

а у него висит окошко с DB-aware контролами это не значит что у него будет висеть пишущая транзакция. Ее не будет до тех пор, пока пользователь не вызовет метод Post

А DataSet у тебя к чему подключен? Не к транзакции? Или используешь ClientDataSet?


 
Johnmen ©   (2004-02-09 12:35) [19]

Добавлю, что вообще непонятно, как можно, при грамотном написании, обеспечить "висящую" пишушую тр-ию ???........
>Пока пользователь вводит данные (через DB-контролы) транзакция
>(созданная дл яввода данных) активна.
У меня неактивна...:)


 
KA_ ©   (2004-02-09 12:37) [20]

>Johnmen © (09.02.04 12:35) [19]

Механизм доступа какой?


 
Johnmen ©   (2004-02-09 12:38) [21]

>KA_ © (09.02.04 12:37) [20]

Что такое "механизм доступа" ?


 
KA_ ©   (2004-02-09 12:40) [22]

>Johnmen © (09.02.04 12:38) [21]
BDE, IBX, FIBPlus, ODBC, чистый IBAPI...


 
Vlad ©   (2004-02-09 12:49) [23]


> KA_ © (09.02.04 12:40) [22]

То что пишущая транзакция не будет висеть - это очевидно. Ты другое скажи: ты что, правда (согласно твоей логике) используешь напр. TStringGrid вместо TDBGrid ?


 
Mike Kouzmine ©   (2004-02-09 12:52) [24]

KA_ © (09.02.04 12:40) [22] Любой.


 
KA_ ©   (2004-02-09 13:01) [25]

>Vlad © (09.02.04 12:49) [23]
Нет, конечно. TDBGrid очень даже использую.


 
Vlad ©   (2004-02-09 13:17) [26]


> KA_ © (09.02.04 13:01) [25]
> >Vlad © (09.02.04 12:49) [23]
> Нет, конечно. TDBGrid очень даже использую.

TDBGrid используешь, и в тоже время ты не сторонник использования других DB-aware контролов. Ничего не понимаю.
Ну... видимо дело вкуса :-)


 
KA_ ©   (2004-02-09 13:17) [27]

>Johnmen © (09.02.04 12:35) [19]
>У меня неактивна...:)

>Mike Kouzmine © (09.02.04 12:52) [24]
> Любой.

Поделитесь, как это реализовано???
BDE - согласен, но одна TDatabase = одна транзакция
IBX - интересно как открыть dataset (для того же ввода данных в DB-контролы) без активной транзакции
FIB+ - как и IBX
IBAPI - тут, конечно, все в твоих руках

Ни с чем другим пока не работал.


 
Vlad ©   (2004-02-09 13:36) [28]


> IBX - интересно как открыть dataset (для того же ввода
> данных в DB-контролы) без активной транзакции

Ты чего-то путаешь. Сам сказал - есть пишущая транзакция, и есть читающая. Так вот, когда открываешь датасет(для ввода, просмотра, удаления, чего угодно) - активна читающая транзакция (и она будет активна не зависимо от того, используешь ты DB контролы или нет). Пишущую транзакцию ты открываешь только в момент непосредственной записи в базу. Ну не причем тут DB-контролы !


 
KA_ ©   (2004-02-09 14:11) [29]

>Vlad © (09.02.04 13:36) [28]
> Ты чего-то путаешь.

Точно.



Страницы: 1 вся ветка

Текущий архив: 2004.03.05;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.016 c
1-12326
vlv
2004-02-25 15:50
2004.03.05
Как определить, какая версия установлена на компьютере?


1-12440
MVova
2004-02-23 11:27
2004.03.05
Работа c UNICODE (получить польский символ)


7-12567
Arsenij
2003-12-17 16:26
2004.03.05
Обмен данными через COM порт


1-12359
tria
2004-02-25 14:21
2004.03.05
Не заходит отладчик в мой модуль


1-12370
Ivolg
2004-02-25 11:49
2004.03.05
Курсор