Nasil baslarsan oyle gider, sunu nolur duzgun yaz:
Visual Fox Pro
1
2
| xx='Cihan'
SQLExec(m.lnHandle,'insert into musteri(rec_no,musteriadi) values(4,?m.xx)') |
recno()'yu unut. Recno filan yok (zaten VFPde de yok aslinda, hesaplanan bir deger). Eger SQL serverda primary key alani olarak IDENTITY kullanirsan o alan otomatik olarak sirayla arttirilip yazilir.
SQL
1
| CREATE TABLE musteri ( rec_no int identity PRIMARY KEY , musteriadi varchar(100) ) |
O zaman senin kodun:
Visual Fox Pro
1
2
| xx='Cihan'
SQLExec(m.lnHandle,'insert into musteri (musteriadi) values (?m.xx)') |
Tabii gun gelecek sen bu kaydin otomatik olusturulan rec_no alanina verilen degeri ogrenmek isteyeceksin (rec_no alaninin recno() ile ilgisi yok oyle isim verip kafa karistirma, ideal isimlendirme tabloAdi + ID gibi mesela "MusteriID" ). O zaman sorun baslayacak. Onu yapmanin N tane yolu var ve ne yazik ki ideal yolu veren kod ben daha gormedim, sen sansli isen gorursun. Temel sorun, o degeri almak icin once o degeri yazman gerekmesi. Her zaman yazma sansin varsa o zaman sorun olmayabilir, basitce geriye scope_identity() dondurebilirsin. O zaman da teker teker insert etmen gerekir. Birden fazla insert etmen gerekirse o ise yaramaz. SQL server'in output clause'dan fayadalanmak su an icin ideal cozumlerden birisi bence.
Oysa sana gerekli olan alti ustu unique bir ID. Bu ID'yi SQL servera yazmasan da onceden alabilsen en iyisi. Neyseki o ID var. GUID olarak taniniyor, SQL serverdaki data tipi "uniqueidentifier". Tabloyu yeniden yaratalim:
SQL
1
2
3
| CREATE TABLE musteri (
musteriID uniqueidentifier rowguidcol PRIMARY KEY nonclustered DEFAULT NewID(),
musteriADI varchar(100) ) |
Bunda, eger musteriID degerini sen vermezsen, SQL server tarafinda NewID() ile yaratilip yazilacak. Sen vermek istersen VFP'de yaratabilirsin, hatta bagli degilken bile yaratabilirsin, seninki de uniqu oldugu garanti edilen bir deger. Yarattigini insert edersin.
Visual Fox Pro
1
2
3
4
5
6
7
8
9
10
11
| * UniqueID.prg
Local pGUID,rGUID
Declare Integer UuidCreate In 'RPCRT4.dll' String @pguid
Declare Integer StringFromGUID2 In 'Ole32.dll' ;
string rguid, String @lpsz, Integer cchMax
pGUID=Replicate(Chr(0),16)
rGUID=Replicate(Chr(0),80)
UuidCreate(@m.pGUID)
StringFromGUID2(m.pGUID,@m.rGUID,40)
Return Strconv(Left(m.rGUID,76),6) |
Ornek:
Visual Fox Pro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| lnHandle = Sqlstringconnect('Driver={SQL Server Native Client 10.0};server=.\SQL2008;Database=test;Trusted_Connection=yes')
TEXT TO m.lcInsert noshow
insert into musteri
(musteriID, musteriADI)
values
(?m.ID,?m.musteriAdi);
ENDTEXT
Id = UniqueID()
musteriAdi = 'Cihan'
SQLExec(m.lnHandle, m.lcInsert)
Id = UniqueID()
musteriAdi = 'Ahmet'
SQLExec(m.lnHandle, m.lcInsert)
SQLDisconnect(0) |
Burada dikkat etmen gereken noktalar:
1) SQL server'a giden emir(ler) text ... endtext arasinda. Yazimi daha kolay, okunabilir, VFP'nin string literal limitleri onemli degil vs. SSMS'de denedigin kodu oldugu gibi kopyele/yapistir sansin var. (not: sondaki noktali virgulun VFP'dekiyle ilgisi yok. O SQL komutun parcasi, komut sonu).
2) Field adlarini aynen SQL serverda yazdigim gibi kullandim. Bu aslinda onemli olmayabilirdi ama ne yazik ki field adinda iI geciyorsa onemli (Turkce ayarlarin oldugu bir makinede musteriadi diye yarattiysan bunun buyuk harfli sekli MUSTERİADİ. Bu ayrintilar insana kafa yediriyor ondan soyledim)
3) Benim tembellik nedeniyle yapmadigim (biraz da simdiden kafan karismasin diye).
a) Ayni komut birden fazla kullanilacaksa, SQLPrepare() ve SQLExec() tercih.
b) SQLExec() sonuclarini kontrol et. Eger -1 ise Aerror() kullanarak nedenine bak.:
Visual Fox Pro
1
2
3
4
| if SQLExec( ... ) < 0
Aerror(aNeden)
MessageBox( aNeden[2] ) && 7'sinden en cok ise yarayan 2
endif |
Not: Bu arada SQLExec()'ten kisa surede kurtulmani tavsiye ederim. Cursoradapter ve ADO. VFP'nin ODBC driverlar ile basi dertte ve bundan sonra da birseyin duzeltilecegini sanmam.
Son düzenleyen, cetinbasoz (15.04.2010 08:14:26)
Yen yaz 1907'ye yolla FB gelsin evinde yensin.
(sonra salaklar ciksin alin terine şike desin)