Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.03.05;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.01 c
1-12441
Pohil
2004-02-23 02:15
2004.03.05
автозагрузка


1-12344
Mox Fulder
2004-02-22 13:14
2004.03.05
Help-file


3-12257
tesseract
2004-02-09 13:02
2004.03.05
Lookup поля в SQL


4-12576
frost
2003-12-28 20:17
2004.03.05
Как из FD : TWin32FindData - получить дату в формате TDateTime


1-12341
dr Tr0jan
2004-02-16 04:30
2004.03.05
Разукрашенная строка в TRichEdit.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский