İşin içinden bir türlü çıkamayınca size yazmak istedim. Sanırım istediğim şey SQL'de yok.
Soru :
HHH adında bir tablomun olduğunu ve içinde de OgrNo Adında Bir Field olduğunu düşenelim .Amacım Şöyle bir insert yapmaktır.
Declare @OgrNo int ,@TabloAdi nvarchar(50) ,@Field nvarchar(50)
Set @OgrNo = 6 Set @TabloAdi = 'HHH' Set @Field = 'OgrNo'
Insert Into @TabloAdi( @Field ) Values( @OgrNo )
Üst Taraftada yazdığım gibi TAblo Adını ve Fieldları da Declareden yani vb'den gelen parametrelerle yapmak istiyorum ama sql böyle birşeyi kabul etmiyor.Daha önceden böyle bir çalışma yapan oldu mu?
diye yapamıyormusun? gelen değişkenlerle dinamik sql sorgusu oluştur onları da executesql diye bi komut vardı ona ver, tam hatırlamıyorum.
ama burda senin yaptığın daha büyük bir hata var tablo adı değişken olmazki? çünkü aynı işi yapan birden fazla tablo olmaz bu bir, bütün tabloların içi farklıdır buda iki
ya sen böyle 1a sınıfına bi tablo 2a sınıfına bi tablo 1c sınıfına bi tablo diyemi yapıyorsun? eğer öyleyse yannış
Benim Amacım vb.netten gelen parametreleri değişken hale getirmek . yani İnsert Update Delete için Ayrı ayrı spler yazmıyacağım .Sadece 1 tane sp ile bütün tablolar için insert yapabiliyor olacağım.
Yani Exec denemesp @Birey_ID = 15 , @Ad = 'xxx' , @Okul = 'yyyy' , @Tablo = 'Kisi' şeklinde parametreler geldiğinde Kisi tablosuna gelen parametreyi kayıt edeceğim. Yine Aynı sp ile şöyle bir kayıt yapabileceğim Yani Exec denemesp @ID = 21 , @Unvan = 'ttt' , @Gorev = 'hhh' , @Tablo = 'Bilgi' . Dikkat edilmesi gereken ikisinde de aynı sp çalışıyor olması .
Gelelim Benim yapamadığım Bölüme ;
Amacım Gelen Parametreyi Hem Text olarak Hemde Value olarak kullanmak . yani vb.netten bana @Birey_ID = 15 şeklinde gelecek . Gelen Parametre Benim Field'ım oluyor. Insert Into fff (Birey_ID) values(@Birey_ID) şeklinde. Yani Gelen Parametrenin Text Bölümünü ( @(et) işareti hariç )Field Alanına , Value Değerini de Values Alanına yazdırmak istiyorum
Aslında sorum basit ama yapılışı zor :) Gelen Parametreyi Text olarak alamıyorum.
Umarım ne demek istediğimi anlatmışımdır.
Aşağıdaki split fonksiyonu kullanarak gelen degeri ayır. Daha sonra döngüye sok gerekli alanları al senin istegine göre belki 2 tane split fonkisyonu da kullanabilirsin. ben aşağıdakini '=' göre böldüm senin gelendegerle rin @Birey_ID = 15,@orgNo=21 şeklinde ise dışarıdan bir tane daha split fonksiyonu çağır döngü içerisinde. onu da ',' ile ayır Biraz ugraşırsan, önceki örneğin de baz alarak kolay bir şekilde yapabilirsin. Biraz ugraş yapamaz isen gene mesaj at tam kodu yazıp göndereyim :) Eger meslegin bu iş ise ugraşıp çözmeni öneririm. Elinde bütün veriler ve örnekler var sadece birleştirip uygulamaya koyacaksın.
Declare cItems cursor for Select Items from [dbo].Split(@gelendeger,'=') Open cItems Fetch Next From cItems Into @Items While @@Fetch_Status=0 Begin -- Burada sql sorgu stringini oluştur. Fetch Next From cItems Into @Items End
CREATE FUNCTION [dbo].[Split](@STRING nvarchar(4000), @Delimiter char(1)) RETURNS @Results TABLE (Items nvarchar(4000)) AS BEGIN DECLARE @INDEX INT DECLARE @SLICE nvarchar(4000) SELECT @INDEX = 1 IF @STRING IS NULL RETURN WHILE @INDEX !=0 BEGIN SELECT @INDEX = CHARINDEX(@Delimiter,@STRING) IF @INDEX !=0 SELECT @SLICE = RTRIM(LTRIM(LEFT(@STRING,@INDEX - 1))) ELSE SELECT @SLICE = RTRIM(LTRIM(@STRING)) INSERT INTO @Results(Items) VALUES(@SLICE) SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX) IF LEN(@STRING) = 0 BREAK END RETURN END
Merhaba,
Öncelikle uğraşıp cevap verdiğin için teşekkür Ederim . Ama sanırım tam anlatamadım derdimi.
Sen split ile ayır demişsin. Ben o fonksiyonları daha önceden yazmıştım . Elimde 1'den 10'a kadar ayırıcı var. Yani Değer = '1,2,3,4,5,3,6,5,4,5,' olsun
Ben onu 2'li olarak 1 2 , 3 4 ,5 3 , 6 5 , 4 5 olarak Ya da 5 li olsun 1 2 3 4 5 , 3 6 5 4 5 olarak ayırabilirim . Ama bana faydası ne orayı anlamadım :(
Declare @BireY_ID int
set @BireY_ID = 15
select * from [dbo].[Split](@Birey_ID, '|')
Sen burda sanırım şöyle anladın . @Birey_ID = Birey_ID | 15 ama bana gelen Parametre öyle olmayacak ki . Bana gelen @Birey_ID = 15 şeklinde olacak
Sana başka bir örnek göndereceğim . Burda yapmak istediğim olayın Zemini Var . Tam karşılamıyor ama amaç bu .
SP'ye gelen parametrelerle kayıt yapmak. Ben Otomasyon Programına destek veriyorum ve burda 1000'e yakın procedure var . Sadece bu basit kodla belki de %70'ini yok edebilirim . Diğer sp'ler joinli create templi sp'ler olacaktır. Ama Sadece 1 tane Insert Sp ile bütün tablolara kayıt işlemini yapabilmektir.
Aşağıdaki sorguda bu olayı gerçekleştiriyorum . Ama burda alanların sabit.
Set @Field = 'OgrNo , Ad , Soyad , Statu' Olarak bana gelmesini istemiyorum.
İstediğim @OgrNo= 1 , @Ad = 'HFF' , @Soyad = 'ÇÇÇÇ' , @Statu = '15' şeklinde gelmesi ve bunları aşağıdaki gibi sorgulamak . (Yani Parametreler parça parça gelecek)
Set @Field = 'OgrNo , Ad , Soyad , Statu' Set @Values = '1 , ''FFF'' , ''ÇÇÇÇ'' , ''15''' set @TabloAdi = 'HHH'
Set @SQL =' Insert Into '+ @TabloAdi +'( '+@Field+' ) Values( '+@Values+' )'
Select @SQL
Anladığım kadarı ile istediğin şey böle bir şey 1 saat kadar ugraşıp düzenledim :) senin dediğin gibi gelen Alanları degerler ile karşılaştırıp sorgu oluşturuyor. Procedure olarak kullanırsan daha hızlı olur table function yapma. Olmaz ise bilgi ver istediğin şekli bulalım. Yorum kısmını da açıp çalışması dizmesine bakabilirsin.
Declare @temp_Fields nvarchar(max) Declare @temp_Values nvarchar(max) Set @temp_Fields ='' Set @temp_Values =''
IF @Field IS NULL RETURN WHILE @INDEX1 !=0 BEGIN SELECT @INDEX = CHARINDEX(@Delimiter,@Field) SELECT @INDEX1 = CHARINDEX(@Delimiter,@Values) IF (@INDEX !=0 and @INDEX1 !=0) Begin SELECT @SLICE = RTRIM(LTRIM(LEFT(@Field,@INDEX - 1))) SELECT @SLICE1 = RTRIM(LTRIM(LEFT(@Values,@INDEX1 - 1))) End Else Begin SELECT @SLICE = RTRIM(LTRIM(@Field)) SELECT @SLICE1 = RTRIM(LTRIM(@Values)) End
Set @temp_Fields = @temp_Fields + @SLICE + ',' Set @temp_Values = @temp_Values + @SLICE1 + ','
---INSERT INTO #test([alanAd],[alanDeger]) VALUES(@SLICE,@SLICE1)
SELECT @Field = RIGHT(@Field,LEN(@Field) - @INDEX) SELECT @Values = RIGHT(@Values,LEN(@Values) - @INDEX1) IF LEN(@Field) = 0 BREAK END
-- işte sana alanlar ve karşılığındaki degerler Set @temp_Fields = SUBSTRING(@temp_Fields,0,LEN(@temp_Fields)) Set @temp_Values = SUBSTRING(@temp_Values,0,LEN(@temp_Values))
--Select @temp_Fields,@temp_Values SET @SQL = 'Insert Into ' +@TabloAdi+'('+ @temp_Fields+') Values('+ @temp_Values + ')' Select @sql
Öncelikle teşekkür ederim . Zahmet edip uğraşmışsın . İstanbulda oturuyorsan sana yemek ısmarlayabilirim :) Uğraştırıyorum seni :) yazarken mahcup oluyorum artık :)
Benim yazdığım ile senin yazdığın kod hemen hemen aynı . Senin yazdığın biraz daha geliştirilmişi.
Galiba ben tam olarak ne istediğimi bilmediğim için sana da düzgün anlatamıyorum ::)
ben sorgudan dönen değer olarak senin yaptığın sorguda Select @sql değerinin dönmesini istiyorum . (Insert Into HHH(@OgrNo,@Ad,@Soyad,@Statu) Values(1,FFF,ÇÇÇÇ,15)) Yani sonucun tam istediğim gibi. Buraya kadar süpersin :) benim bir türlü başaramadığım ve anlatamadığım olay parametre alma olayı .
Bizim ikimizin yaptığı sorguda da değerlerin bize şu şekilde gelmesi lazım Set @Field = 'OgrNo, Ad , Soyad , Statu' Set @Values = '1 ,''FFF'' , ''ÇÇÇÇ'' , ''15'''
Ama ben değerlerin bu şekilde gelmesini istemiyorum . (Bu kısmı üstteki yazılarımda ben sana yanlış anlattım sanırım ya da anlatamadım )
Benim otomasyon programımda kütüphanede dll dosyam var . onunda parametreye değer göndermesi şu şekilde oluyor.
Bir forum alanı düşün . 3 tane text box var . Text_Box değerlerine şöyle id veriyorum . p_OgrNo , p_AdSoyad , p_Unvan dll kodum forumdaki bütün p_ ile başlayan değerleri value değeriyle beraber toplayıp sorguma (stored procedure) gönderiyor . Yani sorguma geliş şekli aynen böyle @OgrNo = 5 , @AdSoyad = 'fff' , @Unvan = 'Doktor'
Bende bu parametleri procedure'dan alıyorum ve kayıt ediyorum. işte her procedure farklı parametreler geldiğinden hepsi için ayrı ayrı insert yazıyorum. Çünkü bu sorgu XXX tablosuna kayıt ederken başka bir forumda da p_adres , p_semt , p_il diye text boxlarım var .Bunu da adres tablosuna kayıt etmek için tekrar sorgu yazıyorum . çünkü bana bu sefer de @adres = 'aaaa' , @il = 'istanbul' , @ilce = 'ataşehir' şeklinde geliyor.
İşte benim amacım bu procedure'ları birleştirmek . Sonuçta hepsi için Aynı ınsert yazıyorum.Tek farkı gelen parametreler ve kayıt ettiğim tablo adı .
Gelelim benim anlatamadığım noktaya .
Ben Bütün hepsi için geçerli olacak tek bir sp yazmak istiyorum .Yani öyle bir sp yazayım ki bana @ogrNo , @adsoyad , @unvan ve ilave olarak @tabloAdi değerleri gelsin bu sorgum gelen tablo adına gerekli parametreleri kayıt etsin
Yine aynı sp'me @adres, @il , @ilce alanı da gelse bu sefer adres alanına kayıt etsin .
İşte içinden çıkamadığım nokta ben naparım da sorguma gelen parametreleri de full değişken yapabilirim.
Yani bana parametreler bu şekilde gelmeyecek Set @Field = 'OgrNo, Ad , Soyad , Statu' Set @Values = '1 ,''FFF'' , ''ÇÇÇÇ'' , ''15'''
Ama başka bir forumda da aynen böle gelecek @adres = 'cc' , @il = 'ist' , @ilce = 'ataşehir' , @tabloadi = 'yy'
Sonuç olarak hepsinde senin yazmış olduğun gibi değer dönecek .yani select @sql şeklinde
Böyle birşey yapmak sql'de mümkün müdür ? Ben gelen parametreler her defasında değişebilen ve bunların hepsini karşılayan bi kod , bi sorgu bulamadım . 4 gündür arıyorum :) Uğraşıp zamanını harcadığın için tekrar teşekkür ederim . Yemek konusunda da ciddiyim :)
Aynen bu şekilde aynı sp fakat farklı parametreleri alabileceğim bu durum yapabilir miyim ? . SQLden mailgönderme olayında dll çağırmıştım sql'den . İlla öyle bişey mi yapmam gerekiyor acaba . Ya da bunların hepsinin dışında şöyle birşey yapabilirsin diyebileceğin bir düşüncen var mı?
Senin anlattıklarından yola çıkarak şöle bir şey yaptım Umarım dogru anlamışımdır :) eger böyle de olmaz ise veya yanlış anlamışız ise Özel den bana bana telefon ve ya email adresini gönder. Proje de Split fonksiyonunu gene kullanacağız . Onu yukarıda vermiştim.
Devamında da şöle bir şey yaptım
-- Anladığım kadarı ile gelen parametrelerin böle bir şey
Declare @gelenDegerler nvarchar(max) Set @gelenDegerler = '@OGrNo=1,@Ad=FFf,@Soyad=ÇÇÇ,@statu=15,@tabloadi = HHH'
Declare @Field nvarchar(max) Declare @TabloAdi nvarchar(50) Declare @SQL nvarchar(max) Declare @INDEX INT Declare @INDEX1 INT Set @INDEX =1 Set @INDEX1=1
Declare @Delimiter char(1) Set @Delimiter=','
Set @gelenDegerler = REPLACE(@gelenDegerler,'@','')
Set @INDEX = CHARINDEX(@Delimiter,REVERSE(RTRIM(LTRIM(@gelenDegerler)))) --Select RIGHT(@gelenDegerler,@INDEX-1) --Select LEN(RIGHT(@gelenDegerler,@INDEX-1)) Set @Field = SUBSTRING(@gelenDegerler,0,LEN(@gelenDegerler)- LEN(RIGHT(@gelenDegerler,@INDEX-1))) Set @INDEX1 = CHARINDEX('=',REVERSE(RIGHT(@gelenDegerler,@INDEX-1))) --Select RTRIM(LTRIM(RIGHT(@gelenDegerler,@INDEX1-1))) Set @TabloAdi = RTRIM(LTRIM(RIGHT(@gelenDegerler,@INDEX1-1))) --Select @TabloAdi --Select @Field
-- Tablo adları ile Fieldleri bir ayırdım Sonra da alaları ayarladım
Declare @temp_Fields nvarchar(max) Declare @temp_Values nvarchar(max) Set @temp_Fields ='' Set @temp_Values =''
Declare @sayi int Set @sayi=0 Declare @Items varchar(50),@Items1 varchar(50) Declare cItems cursor for Select Items from [dbo].Split(@Field,',') Open cItems Fetch Next From cItems Into @Items While @@Fetch_Status=0 Begin --Set @SQL = @SQL + @Items ----------------------------------------------------------- Declare c1 cursor for Select Items as Items1 from [dbo].Split(@Items,'=') Open c1 Fetch Next From c1 Into @Items1 While @@Fetch_Status=0 Begin if((@sayi%2)=0) Set @temp_Fields = @temp_Fields + @Items1 + ',' else Set @temp_Values = @temp_Values+ @Items1 + ','
--Select @sayi Set @sayi = @sayi+1
Fetch Next From c1 Into @Items1 End Close c1 Deallocate c1 ----------------------------------------------------------- Fetch Next From cItems Into @Items End Close cItems Deallocate cItems Set @temp_Fields = SUBSTRING(@temp_Fields,0,LEN(@temp_Fields)) Set @temp_Values = SUBSTRING(@temp_Values,0,LEN(@temp_Values)) --Select @temp_Fields --Select @temp_Values SET @SQL = 'Insert Into ' +@TabloAdi+' ('+ @temp_Fields+') Values('+ @temp_Values + ')' Select @SQL --exec sp_executesql @SQL
CREATE FUNCTION [dbo].[Split](@STRING nvarchar(4000), @Delimiter char(1)) RETURNS @Results TABLE (Items nvarchar(4000)) AS BEGIN DECLARE @INDEX INT DECLARE @SLICE nvarchar(4000) SELECT @INDEX = 1 IF @STRING IS NULL RETURN WHILE @INDEX !=0 BEGIN SELECT @INDEX = CHARINDEX(@Delimiter,@STRING) IF @INDEX !=0 SELECT @SLICE = RTRIM(LTRIM(LEFT(@STRING,@INDEX - 1))) ELSE SELECT @SLICE = RTRIM(LTRIM(@STRING)) INSERT INTO @Results(Items) VALUES(@SLICE) SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX) IF LEN(@STRING) = 0 BREAK END RETURN END
yeni mesaja git
Yeni mesajları sizin için sürekli kontrol ediyoruz, bir mesaj yazılırsa otomatik yükleyeceğiz.Bir Daha Gösterme