SQL Server image (BLOB) tipli alanın "Script" değeri

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Cevapla
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

SQL Server image (BLOB) tipli alanın "Script" değeri

Mesaj gönderen sabanakman »

İyi günler, hiç lazım olur mu bilmem ama binary değer tutan alanın SQL sorgularda çalışacak script değerini elde eden bir fonksiyon hazırlamıştım. Haliyle tersini yapan fonksiyonu da hazır :) . Örnek olarak bir resim alanı olan ve bu tablodaki resim değerleriyle birlikte (mesela insert into ... biçiminde) script oluşturan bir kod yazmamız gerekirse aşağıdaki fonksiyonu kullanarak Stream bilginin SQL Server Script değeri elde edilebilir.

Kod: Tümünü seç

function BinaryToSQL(const Stream:TStream):String;
 function toHex(const B:Byte):String;
 var i:Byte;
 begin
   i:=B and $F;
   if i>9 then Result:=Char(55+i) else Result:=Char(48+i);
   i:=B shr 4;
   if i>9 then Result:=Char(55+i)+Result else Result:=Char(48+i)+Result;
 end;
const Boy=1024;
var i,n,Ri,Len:Integer; S:String; Buffer:array[1..Boy]of Byte;
begin
  Len:=(Stream.Size-Stream.Position)*2;
  if Len>0 then begin
    Inc(Len,2);
    SetLength(Result,Len);
    Result[1]:='0';
    Result[2]:='x';
    //Result[Len]:=#0;
    Ri:=3;
    repeat
      n:=Stream.Read(Buffer,Boy);
      for i:=1 to n do begin
        S:=toHex(Buffer[i]);
        Result[Ri]:=S[1];Inc(Ri);
        Result[Ri]:=S[2];Inc(Ri);
      end;
    until n<Boy;
  end else Result:='NULL';
end;
Burada stream bilginin script değeri oluştuğu için blob alandaki bilginin stream sınıfından bir nesneye kayıt edilmesi gerekmektedir.

Kod: Tümünü seç

var Mem:TMemoryStream; S:String;
begin
  Mem:=TMemoryStream.Create;
  try//Stream'in bu noktada boş olması gerekiyor
    TBlobField(ADOQuery1.FieldByName('resim')).SaveToStream(Mem);
    Mem.Position:=0;//script'i çıkarılacak bilginin başladığı konuma geçilmeli
    S:=BinaryToSQL(Mem);
  finally
    Mem.Free;
  end;
{-->S değişken değeri, 'insert into tbl (resim) values ('+S+')'
şeklinde bir sorgu ile kullanılarak belirtilen resim değeri sorgu ile eklenebilir}
end;
Bir de elimizde script değeri olan binary bir bilgiyi stream'e (sql server veritabanına ihtiyaç duymadan) atabiliriz.

Kod: Tümünü seç

procedure SQLToBinary(const S:String;const Stream:TStream);
var Bitir:Boolean;
 function toBin(S:String):Byte;
 var i,n:Byte; Devam:Boolean;
 begin
   Result:=0;
   Devam:=True;
   repeat
     if S<>'' then begin//48 0-65 A-97 a
       i:=Ord(S[1]); Delete(S,1,1);
       case i of
         48..57:n:=48;
         65..70:n:=55;
         97..102:n:=87;
       else
         if i=0 then Bitir:=True
         else raise
          Exception.CreateFmt('"%s" değeri onaltılık bir değer değildir!...',[S]);
       end;
       Dec(i,n);
       Result:=i or (Result shl 4);
     end;
     Devam:=not Devam;
   until Devam;
 end;
const Boy=1024;
var i,Ri,Len:Integer; Buffer:array[1..Boy]of Byte;
begin
  Len:=Length(S);Ri:=3; Bitir:=False;
  repeat
    i:=1;
    while not Bitir and (i<=Boy) do begin
      Buffer[i]:=toBin(Copy(S,Ri,2));
      if not Bitir then begin
        Inc(Ri,2);Inc(i);
        Bitir:=Ri>Len;
      end;
    end;
    if i>1 then Stream.Write(Buffer,i-1);
  until Bitir;
end;
Bu fonksiyona parametre olarak verilen SQL Script binary bilgisi Stream sınıfından bir nesneye yazılarak gerçek değeri elde edilmektedir.

Kod: Tümünü seç

var Mem:TMemoryStream; S:String;
begin
  Mem:=TMemoryStream.Create;
  try//Stream'in bu noktada boş olması gerekiyor
    Mem.Position:=0;//script'in değerinden elde edilen bilginin başladığı konuma geçilmeli
    //S:='0x96a5e1f0.......//elimizdeki binary değerindeki sql scriptinin değeri
    SQLToBinary(S,Mem);
  finally
    Mem.Free;
  end;
//Mem stream nesnesinde artık binary bilginin karşılığı bulunmaktadır..
end;
Son işlem aslında gereksiz gibi olabilir ama SQL Server yüklü olmayan bir ortamda elimizde bulunan bir scriptteki verilere SQL Server gerektirmeden elde etmemizi sağlar.

Aslında böyle bir konuya gerçek hayatta neredeyse hiç ihtiyaç duyulmayabilir ama ihtiyaç doğuran bazı uygulamalar da yok değil. Mesela bir veritabanın kayıtlarıyla birlikte tamamının scriptinin çıkarıldığı yedekleme veya veritabanları arası kıyas yapan uygulamar için ihtiyaç olabilir belki. İyi çalışmalar.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Cevapla