Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠœΠΈΡ€ InterBase. АрхитСктура, администрированиС ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π±Π°Π· Π΄Π°Π½Π½Ρ‹Ρ… Π² InterBase/FireBird/YaffilΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 45

Автор А Ковязин

v[2] = FieldByName( LQ2 ) AsString,

QryArrField Fields[0] SetArrayValue(v);

QUpdate Params ByName[ LQ ] AsQuad :=

QryArrField.Fields[0] AsQuad;

end;

QryArrField Close;

end;

Π’Π΅ΠΏΠ΅Ρ€ΡŒ всС становится ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΌ ΠŸΠΎΡΠΊΠΎΡ‚ΡŒΠΊΡƒ свойство QiyAnField KindUpdate Ρ€Π°Π²Π½ΠΎ ukModify, Ρ‚ΠΎ QiyArrField выполняСт запрос ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ записи Π² AnayDataSet Π° ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ свойство QiyArrField ExecuteOider Ρ€Π°Π²Π½ΠΎ eoBeforeDefault, Ρ‚ΠΎ запрос (QiyArrField SQL) выполняСтся Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ AirayDataSet Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ свой собствСнный UpdateSQL Π’ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ QryArrField AfterExecute ΠΌΡ‹ всСго лишь ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π·Π°Π½ΠΎΠ²ΠΎ всС Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠ΅ элСмСнты массива ΠΈΠ· Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, подмСняСм Π΄Π²Π° ΠΈΠ· Π½ΠΈΡ… Π½ΠΎΠ²Ρ‹ΠΌΠΈ значСниями, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΊΠ°Π·Π°Π» ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ, ΠΈ Π·Π°Π΄Π°Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° для ArrayDataSet.UpdateSQL Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ArrayDataSet.UpdateSQL Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Ρ‹ всС ΠΏΡΡ‚ΡŒ элСмСнтов массива Π½ΠΎ фактичСски ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Ρ‹ значСния Ρ‚ΠΎΡ‚ΡŒΠΊΠΎ Π΄Π²ΡƒΡ… элСмСнтов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ» ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π² TDBGrid.

Как Π²ΠΈΠ΄ΠΈΡ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Π° с массивами достаточно проста ΠΏΠΎΡΠΊΠΎΡ‚ΡŒΠΊΡƒ всС основныС слоТности Ρ€Π΅ΡˆΠ°ΡŽΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ FIBPlus Π₯ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π±Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ спСциализированный ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, входящий Π² FIBPlus ΠŸΡ€ΠΈΠΌΠ΅Ρ€ DemoArray дСмонстрируСт Ρ€Π°Π±ΠΎΡ‚Ρƒ с TDataSetContamei, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ для синхронизации Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π΄Π²ΡƒΡ… TpFIBDataSet, Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… нашС Π°ΠΏΠ°Ρƒ-ΠΏΠΎΠ»Π΅ (рис 2 64)





Рис 2.64. ИспользованиС TDatabetContamer

ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ DataSetContamerl ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ вмСстС с Database ΠΈ Transaction Π½Π° DataModule Π² нашСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Оба ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° AnayDataSet ΠΈΠ· Ρ€Π°Π·Π½Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌ нашСго прилоТСния ΡΡΡ‹Π»Π°ΡŽΡ‚ΡΡ Π½Π° DataSetContamerl ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ свойства Contamei (рис 2 65)





Рис 2.65. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² TpFIBDataSet ΠΊ DataSetContamerl

ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ TDataSetContamei позволяСт Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ события ΠΎΡ‚ Ρ€Π°Π·Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² TpFIBDataSet, Π° Ρ‚Π°ΠΊΠΆΠ΅ (Ρ€Π°ΡΡˆΠΈΡ€ΡΡ, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, список стандартных событий) ΠΏΠΎΡΡ‹Π»Π°Ρ‚ΡŒ ΠΈΠΌ сообщСния, ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ дСйствия. Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ DataSetContainerl ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π΄Π²ΡƒΡ… событий OnDataSetEvent ΠΈ OnUserEvent


procedure TDataModule2.DataSetsContainerlDataSetEvent(DataSet:

TDataSet;

Event: TKindDataSetEvent);

var Info: string;

begin

if Event = deAfterPost then

if DataSet.Owner.Name = 'Forml' then

DataSetsContainerl.NotifyDataSets(DataSet,

'Form2.ArrayDataSet', 'JOB_TABLE_CHANGED', Info)

else

if DataSet.Owner.Name = 'Form2' then

DataSetsContainerl.NotifyDataSets(DataSet,

'Form1.ArrayDataSet', 'JOB_TABLE_CHANGED', Info);

end;

procedure TDataModule2.DataSetsContainerlUserEvent(Sender:

TObject;

Receiver: TDataSet; const EventName: String; var Info:

String) ;

begin

if EventName = 'JOB_TABLE_CHANGED' then begin

with TpFIBDataSet(Sender) do

if (not CachedUpdates) and

(not TpFIBDataSet(Receiver).CachedUpdates) then

if

TpFIBDataSet(Receiver).Locate('JOB_CODE;JOB_GRADE;JOB_COUNTRY', varArrayOf([

FieldByNamet'JOB_CODE').AsString,

FieldByName('JOB_GRADE').AsString,

FieldByName('JOB_COUNTRY').AsString

]), []) then TpFIBDataSet(Receiver) Refresh

end;

end;


Бмысл дСйствий сводится ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ: послС измСнСния записи Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· Π½Π°ΡˆΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ArrayDataSet происходит событиС AfterPost. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ DataSetContainerl ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ всС события Ρƒ ΠΏΠΎΠ΄Ρ‡ΠΈΠ½Π΅Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Ρ‚ΠΎ срабатываСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ OnDataSetEvent. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Event Ρ€Π°Π²Π΅Π½ deAfterPost, Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ DataSet ссылаСтся Π½Π° Ρ‚ΠΎΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ записи. ΠŸΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π²Ρ‹Π·ΠΎΠ²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° NotifyDataSets DataSetContainerl посылаСт сообщСниС ΠΎΡΡ‚Π°Π²ΡˆΠ΅ΠΌΡƒΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ ArrayDataSet ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ записи. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π½Π° самом Π΄Π΅Π»Π΅ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΡŽΡ‚ ΠΎΠ΄Π½Ρƒ ΠΈ Ρ‚Ρƒ ΠΆΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ, Ρ‚ΠΎ ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ измСнСния. Бинхронизация происходит Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ события OnUserEvent, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ "извСщСния" ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΠΈΠ· ArrayDataSet.

Если ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС "JOB_TABLE_CHANGED" ΠΈ Π½ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· Π½Π°ΡˆΠΈΡ… Π΄Π²ΡƒΡ… ArrayDataSet Π½Π΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Ρ€Π΅ΠΆΠΈΠΌ CachedUpdates (Π² этом случаС Refresh просто Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ даст), Ρ‚ΠΎ ΠΌΡ‹ позиционируСмся Π½Π° ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ запись ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ для Π½Π΅Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ Refresh, ΠΎΠ±Π½ΠΎΠ²ΠΈΠ², Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, запись Π² ΠΎΠ΄Π½ΠΎΠΌ ArrayDataSet послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΎΠ½Π° Π±Ρ‹Π»Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π° Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ ArrayDataSet.

Данная тСхнология являСтся ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠΉ: использованиС DataSetContainer позволяСт Π΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ€Π΅Π·Π²Ρ‹Ρ‡Π°ΠΉΠ½ΠΎ Π³ΠΈΠ±ΠΊΠΈΠ΅ ΠΈ Π² Ρ‚ΠΎ ΠΆΠ΅ врСмя ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹Π΅ схСмы ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈ синхронизации Π΄Π°Π½Π½Ρ‹Ρ… Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ… TpFIBDataSet.

Π Π°Π±ΠΎΡ‚Π° с BLOB-полями

Достаточно часто ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… Ρ€Π°Π·Π½ΠΎΠΎΠ±Ρ€Π°Π·Π½Ρ‹Π΅ нСструктурированныС Π΄Π°Π½Π½Ρ‹Π΅: изобраТСния, OLE-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π·Π²ΡƒΠΊ ΠΈ Ρ‚. Π΄. Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ для этих Ρ†Π΅Π»Π΅ΠΉ сущСствуСт ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… - BLOB ΠŸΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ использованиС BLOB-ΠΏΠΎΠ»Π΅ΠΉ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ простого прилоТСния (см. рис. 2.66), ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅Π³ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ:

CREATE TABLE BIOLIFE (

ID INTEGER NOT NULL,

CATEGORY VARCKAR (15) character set WIN1251 collate

WIN1251,

COMMON_NAME VARCHAR (30) character set WIN1251 collate

WIN1251,

SPECIES_NAME VARCHAR (40) character set WIN1251 collate

WIN1251,

LENGTH_CM_ DOUBLE PRECISION,

LENGTH_IN DOUBLE PRECISION,

NOTES BLOB sub_type 1 segment size 80,

GRAPHIC BLOB sub_type 0 segment size 80);

Для Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, сохранСнных Π² ΠΏΠΎΠ»Π΅ GRAPHIC, ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ стандартный ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ DBIMagel: TDBImage. ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅, Ρ‡Ρ‚ΠΎ запросы ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с BLOB-полями Π½ΠΈΡ‡Π΅ΠΌ Π½Π΅ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ ΠΎΡ‚ запросов со стандартными Ρ‚ΠΈΠΏΠ°ΠΌΠΈ ΠΏΠΎΠ»Π΅ΠΉ:

SelectSQL:

SELECT * FROM BIOLIFE

UpdateSQL:

UPDATE BIOLIFE Set

ID=?NEW_ID,

CATEGORY=?NEW_CATEGORY,

COMMON_NAME=?NEW_COMMON_NAME,

SPECIES_NAME=?NEW_SPECIES_NAME,

LENGTH__CM_=?NEW_LENGTH_CM_,

LENGTH_IN=?NEW_LENGTH_IN,

NOTES=?NEW_NOTES,

GRAPHIC=?NEW_GRAPHIC

WHERE ID=?OLD_ID





Рис 2.66. Π’Π½Π΅ΡˆΠ½ΠΈΠΉ Π²ΠΈΠ΄ Ρ„ΠΎΡ€ΠΌΡ‹ прилоТСния для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с BLOB-полями

InsertSQL:

INSERT INTO BIOLIFE(

ID,

CATEGORY,

COMMON_NAME,

SPECIES_NAME,

LENGTH__CM_,

LENGTH_IN,

NOTES,

GRAPHIC

)

VALUES (

?NEW_ID,

?NEW_CATEGORY,

?NEW_COMMON_NAME,

?NEW_SPECIES_NAME,

?NEW_LENGTH_CM_,

?NEW_LENGTH_IN,

?NEW_NOTES ,

?NEW_GRAPHIC

)

DeleteSQL:

DELETE FROM BIOLIFE

WHERE ID=?OLD_ID

RefreshSQL:

SELECT * FROM BIOLIFE

WHERE

ID=?OLD_ID

ЕдинствСнным ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ΠΌ ΠΎΡ‚ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ… являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ для присвоСния значСния BLOB-ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρƒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ (спСциализированныС ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΈ стандартного класса TStream). НапримСр, Ссли ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π² нашСм ΠΏΠΎΠ»Π΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ· внСшнСго Ρ„Π°ΠΉΠ»Π°, Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ наТатия Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ:

procedure TMainForm.OpenBClick(Sender: ВОbjСсt);

var S. TStream;

FileS: TFileStream;

begin

if not OpenD.Execute then exit;

pFIBDataSetl.Edit;

S : =

pFIBDataSetl.CreateBlobStream(pFIBDataSetl.FieldByName('GRAPHIC') , bmReadWrite);

try

FileS := TFiIeStream.Create(OpenD.FileName, fmOpenRead);

S.CopyFrom(FileS, FileS.Size);

finally

FileS.Free;

S.Free;

pFIBDataSetl.Post;

end;

end;

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Π²Π°ΠΆΠ½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ - ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ BLOB-ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρƒ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ пСрСвСсти pFIBDataSet Π² состояниС рСдактирования Π΄Π°Π½Π½Ρ‹Ρ…. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС это дСлаСтся бСзусловным Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Edit. Π’Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° CreateBlobStream создаСт экзСмпляр ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ класса TFIBDSBlobStream. Π‘ΠΊΠΎΡ€Π΅Π΅ всСго, Π²Π°ΠΌ Π½Π΅ придСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот класс Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ. Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΎΠ½ Π½ΡƒΠΆΠ΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ BLOB-ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Ρ„Π°ΠΉΠ»Π° с ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ bmReadWrite ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ собираСмся ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ содСрТимоС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. ΠŸΠΎΡ‚ΠΎΠΊ S Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ связан с BLOB-ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ, поэтому, копируя Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Ρ„Π°ΠΉΠ»Π° (FileS) Π² ΠΏΠΎΡ‚ΠΎΠΊ S, ΠΌΡ‹ фактичСски присваиваСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρƒ. ΠžΡΡ‚Π°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ измСнСния Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Post Аналогичным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ BLOB-поля Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ внСшний Ρ„Π°ΠΉΠ»:

procedure TMainForm.SaveBClick(Sender: TObject);

var S: TStream;

FileS: TFiIeStream;

begin

if not SaveD.Execute then exit;

if not pFIBDatasetl.FieldByName('GRAPHIC').IsNull then begin

S : =

pFIBDatasetl.CreaceBlobStream(pFIBDatasetl.FieldByName('GRAPHIC '), bmRead);

try

if FileExists(SaveD.FileName) then

FileS := TFileStream.Create(SaveD.FileName, fmOpenWrite)

else

FileS := TFileStream.Create(SaveD.FileName, fmCreate);

FileS.CopyFrom(S, S.Size);

finally

S.Free;

FileS.Free;

end;

end;

end;

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² этой ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π΅ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ bmRead ΠΏΡ€ΠΈ создании ΠΏΠΎΡ‚ΠΎΠΊΠ° S. ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ для сохранСния содСрТимого BLOB-поля Π² Ρ„Π°ΠΉΠ» Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ само ΠΏΠΎΠ»Π΅, поэтому ΠΌΡ‹ создаСм ΠΏΠΎΡ‚ΠΎΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния. Π•Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ простым способом ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡ‡ΠΈΡΡ‚ΠΈΡ‚ΡŒ содСрТимоС BLOB-поля:

procedure TMainForm.ButtonlClick(Sender: TObject);

begin

pFIBDataSetl .Edit;

pFIBDataSetl.FieldByName('GRAPHIC').Clear;

pFIBDataSetl.Post;

end;

Π’ этом случаС Π΄Π°ΠΆΠ΅ Π½Π΅ трСбуСтся ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΈ. Иногда Ρ‚Π°ΠΊΠΆΠ΅ Π½ΡƒΠΆΠ½ΠΎ Π·Π½Π°Ρ‚ΡŒ, являСтся Π»ΠΈ BLOB-ΠΏΠΎΠ»Π΅ пустым ΠΈΠ»ΠΈ Π½Π΅Ρ‚. ΠŸΡ€ΠΈ использовании Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² Ρ‚ΠΈΠΏΠ° TDBImage ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π±Ρ‹Ρ‚ΡŒ Π² этом ΡƒΠ²Π΅Ρ€Π΅Π½Ρ‹. Π‘ΠΎΠ³Π»Π°ΡΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Π½ΠΈΠΊΡ‚ΠΎ Π½Π΅ ΠΌΠ΅ΡˆΠ°Π΅Ρ‚ Π½Π°ΠΌ "Π½Π°Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ" ΠΏΡƒΡΡ‚ΡƒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ ΠΈ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΅Π΅ Π² BLOB-ΠΏΠΎΠ»Π΅ Π’ этом случаС ΠΌΡ‹ Π½Π΅ смоТСм ΠΎΡ‚Π»ΠΈΡ‡ΠΈΡ‚ΡŒ "Π½Π° Π³Π»Π°Π·": Π΅ΡΡ‚ΡŒ Π»ΠΈ ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² BLOB-ΠΏΠΎΠ»Π΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚. Однако ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события OnDataChange ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° DataSourcel: TDataSource:

procedure TMainForm.DataSourcelDataChange(Sender: TObject;

Field: TField) ;

begin

CheckBoxl.Checked :=

pFIBDataSetl.FieldByName('GRAPHIC').IsNull;

end;

Π­Ρ‚ΠΎ событиС вызываСтся, Π² частности, ΠΏΡ€ΠΈ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠΈ ΠΏΠΎ DBGridl; Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΌΡ‹ всСгда ΠΌΠΎΠΆΠ΅ΠΌ ΡƒΠ·Π½Π°Ρ‚ΡŒ, являСтся Π»ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ ΠΏΠΎΠ»Π΅ пустым ΠΈΠ»ΠΈ Π½Π΅Ρ‚.

Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ TpFIBQuery для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с BLOB-полями, Ρ‚ΠΎ ΠΎΠ±Ρ‰ΠΈΠΉ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ остаСтся Ρ‚Π΅ΠΌ ΠΆΠ΅ - Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ TpFIBDataSet, Π²Π°ΠΌ Π½Π΅ потрСбуСтся ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ. НапримСр, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ, которая сохранит Π² Ρ„Π°ΠΉΠ»Ρ‹ всС изобраТСния ΠΈΠ· нашСй Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹:

pFIBQuery.SQL: SELECT * FROM BIOLIFE

procedure TMainForm.Button2Click(Sender: TObject);

var SaveFile: TFileStream;

Index: Integer;

begin

with pFIBQueryl do begin ExecQuery;

Index := 1;

while not Eof do begin

SaveFile := TFileStream.Create(IntToStr(Index) + '.bmp',

fmCreate);

FN('GRAPHIC').SaveToStream(SaveFile);

Next;

inc(Index);