MS SQL Table iki alanım var
1.field [OldContent] [xml] NULL,
2.field [NewContent] [xml] NULL,
şekliden tanımlı bu alanlar olan verileri karşılaştırıp farklı verileri bulup bunu 3.xml alanı olan
3.field [UpdatedContext] [xml] NULL içine yazmak istiyorum.
Bunu sql procedure yazım kuralları ile nasıl yapabiliriz.
örnek verirsem
[OldContent] [xml] NULL, içindeki veri
<row GUEST_ID="13" GUEST_NAME="VEDAT" GUEST_SURNAME="PALA" ADRESS="İZMİR" />
[NewContent] [xml] NULL, içindeki veri ise
<row GUEST_ID="13" GUEST_NAME="VEDAT" GUEST_SURNAME="PALA" ADRESS="İZMİR" CITY="DR" CITY_CODE="35" />
Bu iki veriyi karşılaştırıp
DEĞİŞEN VERİYİ
[UptatedContent] [xml] NULL, içine aşağıdaki kodu yazmam gerekiyor
<row CITY="DR" CITY_CODE="35" />
Teşekkür ederim.
Kısacası yapmak istediğim şey aşağıdaki resimdeki alanda değişen verileri göstermek
http://i57.tinypic.com/2pqky80.jpg
Aşağıdaki resim tam istediğim şey
http://i60.tinypic.com/2cpc615.jpg
İKİ XML KARŞILAŞTIRMA
- softdestek
- Üye
- Mesajlar: 155
- Kayıt: 17 Eyl 2010 03:53
İKİ XML KARŞILAŞTIRMA
En son softdestek tarafından 11 Tem 2015 11:36 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Re: İKİ XML KARŞILAŞTIRMA
Merhaba.
- Senin için PARSE fonksiyonunu yazdım, kolaylık sağlayayım istedim. Artık gerisini getirirsin.
- Parse işlemi yapıldıktan sonra karşılaştırıp yeni bir XML üretmek çocuk oyuncağı.
- Bu örnek ile veri alanlarının yerleri değişse dahi sonuç alabilirsin. Çünkü bileşenlerine alan isimleri bazında ayırıyoruz. Yoksa Önce soyad sonra ad olsaydı ve değerler aynı olsaydı dahi gösterdiğin örnek sayfada değişmiş gibi algılanırdı değil mi?!
- Aşağıdaki örnekte daha parse işemi sırasında dahi aynı veri alanlarının olup olmadığını araştırıp satırları direkt sildirerek filtre edebilir, finalde aListe içeriğini olduğu gibi değişiklikler listesi olarak kullanabilirsin.
- SQL'deki satırları alt alta <row \> <row \> şeklinde eklesen dahi bu parse fonksiyonu hepsini ID'lendirerek aListe içerisine alacağından sıknıtı yaşamazsın. Bir kere EOF döngüsü sonuna kadar bir STRINGLIST veya MEMO benzeri yerde biriktirdiğin XML Row'larını kümülatif olarak fonksiyona verebilir hepsinin bir batında çözümünü sağlayabilirsin.
Takip edeceğin iş akışını yazayım :
(1) a- DocID 1'e ait alanları sırasıyla almak.
. b- DocID 2'de aynı isimli alan var mı diye aramak.
. c- Varsa değerlerini karşılaştırmak
. d- Değerler farklı ise yeni değeri değişmiş olarak kodlamak.
(2) a- DocID 1'deki alan DocID 2'de yok ise NULL çekip değeri değişmiş deyip elinizdeki tek değeri yazmak
(3) bu işlemleri bir Doc1-> Doc2 yönünde yaptığınız gibi bir de tersini Doc-2'den Doc-1 yönünde yapmak. Çünkü görebildiğim üzere Doc-2'de olan Doc-1'de olmayan alanlar da olabiliyor ...
Kullanımı :
- Senin için PARSE fonksiyonunu yazdım, kolaylık sağlayayım istedim. Artık gerisini getirirsin.
- Parse işlemi yapıldıktan sonra karşılaştırıp yeni bir XML üretmek çocuk oyuncağı.
- Bu örnek ile veri alanlarının yerleri değişse dahi sonuç alabilirsin. Çünkü bileşenlerine alan isimleri bazında ayırıyoruz. Yoksa Önce soyad sonra ad olsaydı ve değerler aynı olsaydı dahi gösterdiğin örnek sayfada değişmiş gibi algılanırdı değil mi?!
- Aşağıdaki örnekte daha parse işemi sırasında dahi aynı veri alanlarının olup olmadığını araştırıp satırları direkt sildirerek filtre edebilir, finalde aListe içeriğini olduğu gibi değişiklikler listesi olarak kullanabilirsin.
- SQL'deki satırları alt alta <row \> <row \> şeklinde eklesen dahi bu parse fonksiyonu hepsini ID'lendirerek aListe içerisine alacağından sıknıtı yaşamazsın. Bir kere EOF döngüsü sonuna kadar bir STRINGLIST veya MEMO benzeri yerde biriktirdiğin XML Row'larını kümülatif olarak fonksiyona verebilir hepsinin bir batında çözümünü sağlayabilirsin.
Takip edeceğin iş akışını yazayım :
(1) a- DocID 1'e ait alanları sırasıyla almak.
. b- DocID 2'de aynı isimli alan var mı diye aramak.
. c- Varsa değerlerini karşılaştırmak
. d- Değerler farklı ise yeni değeri değişmiş olarak kodlamak.
(2) a- DocID 1'deki alan DocID 2'de yok ise NULL çekip değeri değişmiş deyip elinizdeki tek değeri yazmak
(3) bu işlemleri bir Doc1-> Doc2 yönünde yaptığınız gibi bir de tersini Doc-2'den Doc-1 yönünde yapmak. Çünkü görebildiğim üzere Doc-2'de olan Doc-1'de olmayan alanlar da olabiliyor ...
Kod: Tümünü seç
function ParseEt( strDoc1, strDoc2: String ): String;
Type
pVeri = ^tveri;
tVeri = Record
DocId : Word; // Doc1 mi Doc2 mi olduğu
Satir,
AlanIdx : Integer;
AlanAdi,
AlanDeger : String;
end;
Procedure ParseEdilsin( strDoc: String; DocID:Word; Liste:TStrings );
Const
strSatirBasi = '<ROW';
Var
Veri : pVeri;
iSat, Idx : Integer;
begin
iSat := 0;
while POS( strSatirBasi, UpperCase(strDoc) ) > 0 do // Tek satır da olsa birden fazla da olsa çalışır...
begin // Satır Başı...
System.Delete( strDoc, 1, POS( strSatirBasi, UpperCase(strDoc) ) + Length(strSatirBasi)-1 );
inc(iSat);
strDoc := Trim(strDoc);
Idx := 0;
while Pos('="', strDoc) > 0 do // Başlık ve Değer var...
begin
New(Veri);
Inc(Idx);
Veri.DocId := DocID; // Doc-1 veya Doc-2 olduğunu ifade ediyoruz...
Veri.Satir := iSat;
Veri.AlanIdx := Idx;
Veri.AlanAdi := Trim( Copy(strDoc, 1, Pos('="', strDoc)-1 ) );
System.Delete( strDoc, 1, Pos('="', strDoc) + 1 );
Veri.AlanDeger := Trim( Copy(strDoc, 1, Pos('"', strDoc)-1 ) );
System.Delete( strDoc, 1, Pos('"', strDoc) );
Liste.AddObject( Veri.AlanAdi, TObject(Veri) );
end;
end;
end;
Var
aListe : TStringList;
i : Integer;
begin
Result := '';
aListe := TStringList.Create;
// Aynı şeyi iki defa yazmayalım diye procedure yaptım...
ParseEdilsin( strDoc1, 1, aListe );
ParseEdilsin( strDoc2, 2, aListe );
// Şimdi "aListe" içerisinde Başlık ve Değer içerikleri
// tümüyle parse edilmiş şekilde var...
// artık karşılaştırma yapabiliriz...
for i := 0 to aListe.Count - 1 do
begin
Result := Result + Format('Doc:%.2d @ Id:%d - Idx:%.2d : %s = %s'#13, [
pVeri( aListe.Objects[i] ).DocId
, pVeri( aListe.Objects[i] ).Satir
, pVeri( aListe.Objects[i] ).AlanIdx
, pVeri( aListe.Objects[i] ).AlanAdi
, pVeri( aListe.Objects[i] ).AlanDeger
]);
end;
// Sonunda hafızayı boşaltıp free edelim...
for i := 0 to aListe.Count - 1
do Dispose( pVeri(aListe.Objects[i]) );
aListe.Clear;
aListe.Free;
end;
Kod: Tümünü seç
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Memo3.Lines.Text := ParseEt( Memo1.Lines.Text, Memo2.Lines.Text );
end;
- softdestek
- Üye
- Mesajlar: 155
- Kayıt: 17 Eyl 2010 03:53
Re: İKİ XML KARŞILAŞTIRMA
Çok teşekkür ederim...Bunu sql server içerisinde procedure ile yapabilsek süper olurdu ama sorun değil..Bunu delphide function olarak yazıp sql server dll fonksiyon olarak kullanmaya çalışayım..
Loggin olayı çok güzel oldu her tabloaya sadece bir triger ile kolaylıkla monte ediyorum.
Fakat sadece updatecontent de değişen alanları gösterme kaldı...Sqlde procedure yazmaya çalışıyordum bende...
Loggin olayı çok güzel oldu her tabloaya sadece bir triger ile kolaylıkla monte ediyorum.
Fakat sadece updatecontent de değişen alanları gösterme kaldı...Sqlde procedure yazmaya çalışıyordum bende...