Форум: "Базы";
Текущий архив: 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