1

Konu: Visual Foxproda index kırılması

Visual Foxproda oluşan index kırılmalarına karşı ne gibi önlemler alınabilir. Uzman arkadaşlarımızın bu konudaki önerilerini bekliyorum. İlginiz için şimdiden teşekkür ederim.

2

Re: Visual Foxproda index kırılması

bence en iyisi PACK veya REINDEX komutu ile belli zaman aralıklarında düzenlemek
aşağıdakini örneğin aydabir geceyarısı çalıştır. (kodu doğaçlama kontrolsüz yazdım)

=ADIR(fa,"c:\dosyaklasörü\*.dbf")
FOR Xi=1 TO ALEN(fa,1)
  WAIT fa[Xi,1] NOWAIT WINDOW
  m.hFile = FOPEN(fa[Xi,1], 12)
  IF (m.hFile > 0) && Not used   
    FCLOSE(m.hFile)       
    USE (fa[Xi,1]) EXCL
    PACK    && REINDEX
    USE 
  ENDI
ENDF

VFP9 SP2

3

Re: Visual Foxproda index kırılması

"kırılmak == bozulmak" anlama geliyorsa:

Ben kendim için bu sorunu şöyle çözdüm:
1. Uzun süredir artık FoxPro'nun kendi veritabanını kullanmiyorum.
2. Eski yazdığım programlarda:
  - Dosyayalarımı sadece kullanacağım vakit açıyorum, sonra hemen kapatıyorum
  - Programın servis modülünde "dosya bakım" diye bir seçenek var:  tabloların tüm index'lerini siliyor, tabloya "PACK" komutunu uyguluyor  ve sonra tekrar tüm index'leri yaratıyor. Bir müşteri beni aradığında, ilk sorum "dosya bakım yaptınızmı?" oluyor. Ekseri yapmamış oluyorlar, ve yaptıkdan sonra ekseri cevap olarak "Aaaa, düzeldi!"  duyuyorum.

Bir projenin bitmesi için 3 seçenek vardır: hızlı, ucuz, iyi. Bu seçeneklerden iki tanesini seçiniz.

4

Re: Visual Foxproda index kırılması

-Kesintisiz guc kaynagi
-Dosyalarin mumkun oldugu kadar az acik tutulmasi.

En saglami da VFP yerine SQL server gibi bir database kullanmak:)

5

Re: Visual Foxproda index kırılması

üstadlara ek olarak, naçizane birkaç ekleme:

-  tabloları kapatırken Windows'un buffer'daki datayı yazarak boşaltmasını sağlamak için;
   

Visual Fox Pro
FLUSH IN (tablom) FORCE

USE IN (SELECT(tablom))

- bir tabloyu sadece data almak için açacaksam, onu read-only yapıyorum

Visual Fox Pro
USE tablom NOUPDATE

6

Re: Visual Foxproda index kırılması

konu acilmisken benden de bir soru;

network ortaminda calisan cok kullanci bir yazilimim var.  buffer 5 kullaniyorum actigim dosyalarda. yeni fis actigimda fisler karismasin diye once dosyayi kilitleyip sonra fis numarasi alip hemen tableupdate yapiyorum. buna ragmen fislerde karisma oluyor. yani ayni anda birlikte fis acan iki kullanicinin zaman zaman fis satirlari karisiyor. nedeni sizce nedir ? bir oneriniz var mi?

7

Re: Visual Foxproda index kırılması

Öncelikle ESAS fiş numarasını kaydetmeden önce kesinleştirme,
işlemler sırasında geçici bir fiş numarasını 

Visual Fox Pro
SYS(2015) && veya illa numerik istiyorsan

CHRT(SYS(2015),'_ABCDEFGHIJKLMNOPQRSTUVWXYZ','123456789012345678901234567')

benzeri metod ile yaratıp, kaydı yukardaki unique numara ile tamamlayıp, sonraki komut satırında esas fiş no ile değiştirebilirsin --- veya ----
kayıt sırasında kaydı yeni fiş no ile yapılabilinir (INSERT INTO (APPE BLAN değil) )
(muhtemelen çakışma milisaniyeden az sürece kalır)
--- başka aklıma gelen ---
VFP yeni kayıtta yeni RECNO() yu - değer olarak kullanıyor, kesinleştiği noktada + yaparak kaydı tamamlıyor.
benzeri algoritma da geliştirebilirsin
---
TABLEUPDATE - FLUSH benzeri fonksiyonlarla hep kötü tecrübem oldu.
Yeni esas fiş numarası alırken nasıl yaptığını bilmiyorum:

Visual Fox Pro
SELECT MAX(yenifişno) AS yfn FROM fişdosya INTO CURS curYenifiş

m.yenifişno=NVL(curYenifiş.yfn,0)+1
INSERT INTO fişdosya (fişno, ...) VALUES (m.yenifişno, ...)

benzeri kodla daha olumsuz tecrübem olmadı

VFP9 SP2

8

Re: Visual Foxproda index kırılması

aydinufuk yazdı:

konu acilmisken benden de bir soru;

network ortaminda calisan cok kullanci bir yazilimim var.  buffer 5 kullaniyorum actigim dosyalarda. yeni fis actigimda fisler karismasin diye once dosyayi kilitleyip sonra fis numarasi alip hemen tableupdate yapiyorum. buna ragmen fislerde karisma oluyor. yani ayni anda birlikte fis acan iki kullanicinin zaman zaman fis satirlari karisiyor. nedeni sizce nedir ? bir oneriniz var mi?

Ben numaralar icin tamamen ayri bir tablo tutuyorum.

IDS: tableName c(50), nextID i - index on upper(tablename) tag tableName

Kod'da soyle (stored procedure)

Visual Fox Pro
Function NewID

    Lparameters tcAlias,tnCount
    Local lcAlias, lnOldArea, lcOldReprocess, lcTable, lnTagNo, lnNewValue, lnLastValue, lcOldSetDeleted
    lnOldArea = Select()
    lnOldReprocess = Set('REPROCESS')
    * Uppercase Alias name
    lcAlias = Upper(Iif(Parameters() = 0, Alias(), tcAlias))
    * Lock reprocess - try once
    Set Reprocess To 1
    If !Used("IDS")
        Use ids In 0
    Endif
    * If no entry yet create
    If !Seek(lcAlias, "Ids", "tablename")
        Insert Into ids (tablename, NextID) Values (lcAlias,0)
    Endif
    * Lock, increment id, unlock, return nextid value
    Do While !Rlock('ids')
        * Delay before next lock trial
        lnStart = Seconds()
        Do While Seconds()-lnStart < 0.01
        Enddo
    Enddo
 
    lnLastValue = ids.NextID
    lnNewValue  = m.lnLastValue + Evl(m.tnCount,1)
 
    *Try to query primary key tag for lcAlias
    lcTable = Iif( Used(lcAlias),Dbf(lcAlias), Iif(File(lcAlias+'.dbf'),lcAlias,''))
    lcTable = Evl(m.lcTable,m.lcAlias)
    If !Empty(lcTable)
        Use (lcTable) In 0 Again Alias '_GetPKKey_'
        For m.lnTagNo=1 To Tagcount('','_GetPKKey_')
            If Primary(m.lnTagNo,'_GetPKKey_')
                m.lcOldSetDeleted = Set("Deleted")
                Set Deleted Off
 
                Select '_GetPKKey_'
                Set Order To Tag (Tag(m.lnTagNo,'_GetPKKey_')) ;
                    In '_GetPKKey_' Descending
                Locate
                lnLastValue = Max(m.lnLastValue, Evaluate(Key(m.lnTagNo,'_GetPKKey_')))
                lnNewValue = m.lnLastValue + Evl(m.tnCount,1)
 
                If Upper(m.lcOldSetDeleted) == 'ON'
                    Set Deleted On
                Endif
                Exit
            Endif
 
        Endfor
        Use In '_GetPKKey_'
        Select ids
    Endif
 
    * Increment
    Replace ids.NextID With m.lnNewValue In 'ids'
    Unlock In 'ids'
    Select (lnOldArea)
    Set Reprocess To lnOldReprocess
    Return ids.NextID
Endfunc

Bunu database'ine SP olarak ekledikten sonra ornek kodlar:

Visual Fox Pro
open database dbName

lnID = NewID("Musteriler") && musteriler icin 1 ID al
lnID = NewID("Musteriler", 10) && musteriler icin blok 10 ID al - gelen kullanacagin son numara. 88 geldiyse 88-10+1 ilk. 79-88 senin

Tablolarda ID alanin icin default deger:

Visual Fox Pro
NewID("TabloAdi")

Bu da SQL/VFP OLEDB icin getNextID (oApp custom nesne, o sirada kullanilan db icin connectionstring tutuyor):

Visual Fox Pro
Lparameters tcTableName, tnCount

IF VARTYPE(oApp)!='O' AND VARTYPE(_screen.oApp) = 'O'
    oApp = _screen.oApp
endif
 
Local loConn as 'ADODB.Connection',loCommand as 'ADODb.Command',loRS as 'ADODb.RecordSet',lnReturn
loConn = Createobject('ADODB.Connection')
loCommand = Createobject('ADODB.Command')
loConn.ConnectionString = oApp.ADODataConnectionString
loConn.Open
loCommand.ActiveConnection = loConn
loCommand.CommandType = 4 && stored procedure
Do Case
    Case oApp.DataMode == 'SQL'
        loCommand.CommandText = 'NextID'
        loCommand.Parameters.Refresh
        loCommand.Parameters('@tableName').Value = m.tcTableName
        loCommand.Parameters('@nRows').Value = EVL(m.tnCount,1)
        loCommand.Execute
        lnReturn = loCommand.Parameters('@end').Value
    Case oApp.DataMode == 'VFP'
        loCommand.CommandText = Textmerge('NewID("<<m.tcTableName>>",<<EVL(m.tnCount,1)>>)')
        loRS = loCommand.Execute
        lnReturn = loRS.Fields(0).Value
        loRS.Close
Endcase
loConn.Close
Return m.lnReturn

Dikkat edersen lock sadece ilgili record'da RLock(). Lock icin yarismayi onlemek icin reprocess 1 ve arada beklemeler var. Sorunsuz calisiyor yillardir, cok sayida musteride.

Not: Tabii gonlum yine de GUID'den yana hic boyle dertleri yok. Yenilerde NOSQL veri tabanlariyla ilgileniyorum, orada ID'ler hep GUID tarzi ve cok cok hizlilar (Ilgilenme 'oynama' safhasinda ve .Net ile. VFP icin zaten cogunun hic destegi yok). Simdilik hizlari, kolayliklari karsisinda agzim sulaniyor o kadar.

9

Re: Visual Foxproda index kırılması

aydinufuk yazdı:

konu acilmisken benden de bir soru;

network ortaminda calisan cok kullanci bir yazilimim var.  buffer 5 kullaniyorum actigim dosyalarda. yeni fis actigimda fisler karismasin diye once dosyayi kilitleyip sonra fis numarasi alip hemen tableupdate yapiyorum. buna ragmen fislerde karisma oluyor. yani ayni anda birlikte fis acan iki kullanicinin zaman zaman fis satirlari karisiyor. nedeni sizce nedir ? bir oneriniz var mi?

örnegin table'de FISNO  adında bir indexli  field var    buda 1,2,3,4,5,... diye digiyor
kullanıcı fişi kaydettiği anda

set orde to fisno
go botto
yeniID=fisno+1 şeklinde ID elde ediyorum
vede yeni fiş noyu yeni ID kullanrak kaydedıyorum.
Bunla ilgili hiç sıkıntı yaşamadım.Sadece index kırılması hariç tabiki
Bu yöntem basit gibi görünüyor ama eksiği varmı sizce?

10

Re: Visual Foxproda index kırılması

Ben Cetin hocamin yontemini kullaniyorum IDS.dbf ister DE de ister load ta use ile acilsin buffermode a dahil edilmiyor /ben etmiyorum /  yani yeni islemno,ftno vs ne isterseniz isteyin siradakini getiriyor arada bosluklar( takip eden numaralar) olabilir ama cakisma kesinlikle olmuyor...Yani hep garanti ve siradaki numara aliniyor...