Konuyu Oyla:
  • Derecelendirme: 5/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Sql serverden cliente part part download
#1
Merhaba arkadaşlar ,

Yapılmak istenen 
Ms sql de server tarafında varbinary(max) olarak tutulan veriyi
Client tarafında dosyayı parça parça şeklinde almak 

Amaç
Client tarafında örneğin 20mb bir dosya olduğun da bunu query içersinde bir field olarak tek seferde çekmemek, kullanılan ağı akıllı switch olmasa bile yormamak .

Düşünce 
Sql serverde varbinary(max) alanının boyutunu alıp , belirli parçalara  bölerek tek tek alırken tread in içerisinde bir while döngüsü ile tamamını alırken her dongude sleep(5) gibi bir ekleme yaparak ağı rahatlatmak 

Arastirdim ancak partial download örnekleri hep IdHttp ve IdFtp üzerinden yapmışlar. 

Konuda bilgisi olan varsa aydinlatirsa sevinirim 

Teşekkürler
Cevapla
#2
Merhaba.

- İlk problem SELECT satırına veri içeren field'i almadan sadece boyutunu okuyabilir miyiz sorusunun cevabını aramak olurdu. Şahsen parça parça almanın ilk adım bu olurdu diye değerlendiriyorum.

SELECT içerisinde VarChar alanımın string uzunluğunu  
SELECT Uzunluk = DATALENGTH( [DogumYeri] )

şeklinde ölçümleyebiliyorum. Yani kaç karakter ise o Uzunluk alanı ilgili sayı ile doluyor. 

Sizin durumda sürekli aynı rakam mı yoksa veri miktarı kadar mı değer dönüyor manasında nasıl sonuç verir, deneyip bildirirseniz ben de öğrenmiş olurum.  Idea
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#3
DECLARE @ID  INT = 8 -- ÇEKİLECEK ID
DECLARE @COUNTER  INT = 99    -- KAÇINCI PARSE
DECLARE @BOLEN    INT = 100 -- TOPLAM PARSE
DECLARE @DATALEN  INT
DECLARE @DATASTRT INT
DECLARE @DATAMAX  INT
DECLARE @DATANEW  INT
SET @DATALEN  = (SELECT LEN(master.dbo.Fn_varbintohexstr(Picture)) FROM CATEGORIES WITH(NOLOCK) WHERE CategoryID=@ID)
SET     @DATANEW  = @DATALEN/@BOLEN
SET     @DATASTRT = (@DATANEW*(@COUNTER-1))+1
SET     @DATAMAX  = CASE WHEN @COUNTER = @BOLEN THEN @DATALEN ELSE @DATANEW*@COUNTER END
SELECT 
SUBSTRING(Upper(master.dbo.Fn_varbintohexstr(Picture)), @DATASTRT, @DATAMAX)
FROM CATEGORIES WITH(NOLOCK) WHERE CategoryID = @ID

Şu şekilde parseladım birleştirip data bozuluyormu denemek lazım. NORTWIND databasinde deneyebilirsiniz.
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#4
Merhaba,

Araştırmalarıma rağmen veritabanı ile bir connection kurup parça parça çekilecek orjinal bir yöntem bulamadım.
Ancak bunu sql tarafı ile hallettim.

İlk adımda:
sql Datalength fonsiyonu ile:

SELECT uzunluk = DATALENGTH(COLUMN_NAME)  FROM  TABLE_NAME;

ilgili verinin uzunluğunu alıyoruz.

İkinci adımda:
Sql tarafında
SUBSTRING( string, start_position, length )
ile parça parça alabiliyoruz. Ancak bize en fazla 64kb lık bir bilgi veriyor.

Örneğin

20mb bir dosyamız olduğunda (20971520byte). 
64kblık(65536byte) parçalar halinde aldığımızda
320 defa veri tabanına gidip gelmemiz gerekiyor.


Yapılan:
1. olarak başta dosya boyutu aldım
2. olarak Dosya boyutu / 327680 ile döngü sayımı hesapladım(327680byte=320kb)
3. olarak Select ifademiniz içerisinde 5 tane substring ile (O dosyanın belirli bir pozisyonundan başlayan ve 64kb+64kb+ 64kb+ 64kb+64kb toplamda 320kb = 0,3mb) veri çeken
ve bunu TMemoryStream'a yazan bir algoritma geliştirdim. ve her döngümün içerisine sleep(10) koydum. 
(Sleep komutu threadlerde hayati değer taşıdığı gibi burada da öyle olduğunu düşünüyorum)

Sonuç:
20mb dosyayı 64 defa veri tabanına giderek. Parça parça alıp TMemoryStreamda topladım daha sonra kaydettim

Bunu SQL tarafında bir fonksiyon, prosedür ile yapmamamın sebebi dinamik olması gerekli fonksiyonum

Function SqlVeriyiParcalayarakGetir(aKolonAdi, aTabloAdi, aWhereSarti : String) : TMemoryStream;
begin

//kod

end;

şeklinde yaptım. Benim çözümüm bu şekilde
Algoritmayı vermememin sebebi bunu kopyalayıp yapıştırmak yerine, buna ihtiyacı olan kişinin de bir araştırma yapması.Belki benden iyi bir çözüm bulur yol gösterir.

Yardımcı olan arkadaşlara teşekkür ediyorum.
Teşekkürler.
Cevapla
#5
Tebrikler
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#6
tebrikler güzel bir yöntem olmuş .
Cevapla
#7
(29-09-2018, Saat: 09:35)malitutuncu Adlı Kullanıcıdan Alıntı: Merhaba,

Araştırmalarıma rağmen veritabanı ile bir connection kurup parça parça çekilecek orjinal bir yöntem bulamadım.
Ancak bunu sql tarafı ile hallettim.

İlk adımda:
sql Datalength fonsiyonu ile:

SELECT uzunluk = DATALENGTH(COLUMN_NAME)  FROM  TABLE_NAME;

ilgili verinin uzunluğunu alıyoruz.

İkinci adımda:
Sql tarafında
SUBSTRING( string, start_position, length )
ile parça parça alabiliyoruz. Ancak bize en fazla 64kb lık bir bilgi veriyor.

Örneğin

20mb bir dosyamız olduğunda (20971520byte). 
64kblık(65536byte) parçalar halinde aldığımızda
320 defa veri tabanına gidip gelmemiz gerekiyor.


Yapılan:
1. olarak başta dosya boyutu aldım
2. olarak Dosya boyutu / 327680 ile döngü sayımı hesapladım(327680byte=320kb)
3. olarak Select ifademiniz içerisinde 5 tane substring ile (O dosyanın belirli bir pozisyonundan başlayan ve 64kb+64kb+ 64kb+ 64kb+64kb toplamda 320kb = 0,3mb) veri çeken
ve bunu TMemoryStream'a yazan bir algoritma geliştirdim. ve her döngümün içerisine sleep(10) koydum. 
(Sleep komutu threadlerde hayati değer taşıdığı gibi burada da öyle olduğunu düşünüyorum)

Sonuç:
20mb dosyayı 64 defa veri tabanına giderek. Parça parça alıp TMemoryStreamda topladım daha sonra kaydettim

Bunu SQL tarafında bir fonksiyon, prosedür ile yapmamamın sebebi dinamik olması gerekli fonksiyonum

Function SqlVeriyiParcalayarakGetir(aKolonAdi, aTabloAdi, aWhereSarti : String) : TMemoryStream;
begin

//kod

end;

şeklinde yaptım. Benim çözümüm bu şekilde
Algoritmayı vermememin sebebi bunu kopyalayıp yapıştırmak yerine, buna ihtiyacı olan kişinin de bir araştırma yapması.Belki benden iyi bir çözüm bulur yol gösterir.

Yardımcı olan arkadaşlara teşekkür ediyorum.
Teşekkürler.


Veriyi tek parça halinde elde ettiğinizde bütünlüğünde bir bozulma veya farklılık oluştu mu?
YouTube Delphi Tips
"Mantıklı adam kendini dünyaya uyarlar; mantıksız adam ise dünyayı kendine uydurmakta inat eder. Bu nedenle, tüm ilerleme o inatçı adama bağlıdır." - George Bernard Shaw
WWW
Cevapla
#8
Yok hocam veriyi bozulmadan alıyorum, 128kb partlar halinde çekiyorum, veritabanin dan memory streamda bittiği yerden ikinci partı ekleyeceksiniz. Ve bunu döngü haline getirdiğimiz de, string yerleri parametre olarak aldığımız da gayet güzel çalışıyor, 
Böylelikle kullanıcıya serverden çektiği dosyanin ne kadarı indiğini bilgisini progressbar ile verebiliyoruz. Thread içindede arka planda cekebiliyoruz.

Şimdi de veri tabanına ağı yormadan  bir alana dosyayı parça parça yüklemeye bakıyorum
Cevapla
#9
Daha önce bildiğim ya da kullandığım bir yöntem değil, parça parça yazmak için Write komutunu kullanabilirsiniz belki...
.WRITE (expression,@Offset,@Length)
WWW
Cevapla
#10
(03-10-2018, Saat: 19:31)malitutuncu Adlı Kullanıcıdan Alıntı: Yok hocam veriyi bozulmadan alıyorum, 128kb partlar halinde çekiyorum, veritabanin dan memory streamda bittiği yerden ikinci partı ekleyeceksiniz. Ve bunu döngü haline getirdiğimiz de, string yerleri parametre olarak aldığımız da gayet güzel çalışıyor, 
Böylelikle kullanıcıya serverden çektiği dosyanin ne kadarı indiğini bilgisini progressbar ile verebiliyoruz. Thread içindede arka planda cekebiliyoruz.

Şimdi de veri tabanına ağı yormadan  bir alana dosyayı parça parça yüklemeye bakıyorum

Bittiğinde bizimle de paylaşırsan sevinirim  
Teşekkürler kolay gelsin şimdiden
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Http aSync Download'ı Geliştirmek omer 0 1.070 02-03-2022, Saat: 16:30
Son Yorum: omer
  Webbrowser üzerinden Download sorunu COMMANDX 3 2.286 05-05-2021, Saat: 09:57
Son Yorum: COMMANDX
  Multi-Thread Partial Download yhackup 0 2.172 26-10-2018, Saat: 16:56
Son Yorum: yhackup



Konuyu Okuyanlar: 1 Ziyaretçi