Mssql değişken table ismi ve string execute kullanımı

MS SQL Server veritabanı ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Cevapla
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mssql değişken table ismi ve string execute kullanımı

Mesaj gönderen ofenX »

Merhaba,
Ben mssql i tam bilmiyorum. Bir arkadaşa yardımcı olmak için bir programcık yazayım dedim. 4-5 tablodan veri çekmek gerekiyor. Bu tablo isimleri değişken olacak. Örneğin bir tablo ismi LG_200_01_INVOICE olabilirken başka bir sorgulamada LG_001_01_INVOICE olabilir. Yani firma no ve donem no herzaman değişebilir. Ben de asıl konuya girmeden ufak bir deneme ile istediğim sonuca ulaşayım dedim.
Yaptığım aramalarda bunu string execute ile yapabileceğimi sandım. Ama bu defa şöyle bir sorun çıktı.
Aşağıdaki kodda istediğim sonuç geliyor.

Kod: Tümünü seç

declare @DOSYA VARCHAR(255)
DECLARE @SQLKOMUTU VARCHAR(4000)
DECLARE @SONUC VARCHAR(16)
SET @SONUC =(SELECT NEWSERINO FROM KYCEKNODB WHERE NEWSERINO='266 17 93')
SELECT @SONUC
Ama dosya ismi aşağıdaki gibi değişken olunca aynı sonucu alamıyorum.

Kod: Tümünü seç

declare @DOSYA VARCHAR(255)
DECLARE @SQLKOMUTU VARCHAR(4000)
DECLARE @SONUC VARCHAR(16)

SET @DOSYA='KYCEKNODB'
SET @SQLKOMUTU ='SELECT NEWSERINO FROM '+@DOSYA +' WHERE NEWSERINO=''223 99 00'''
SET @SONUC= EXEC (@SQLKOMUTU)
veya

Kod: Tümünü seç

SET @SONUC= (EXEC (@SQLKOMUTU))
şeklinde kullanamıyorum.
Konuyu özetlemek gerekirse tablo adlarını değişkenlere atayıp, sql komutları ile daha sonra nasıl kullanabilirim.

Herkese iyi çalışmalar.
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Mesaj gönderen Hakan Can »

Kod: Tümünü seç

IF (@DOSYA = 'KYCEKNODB') THEN SELECT @SONUC = NEWSERINO FROM KYCEKNODB WHERE NEWSERINO=''223 99 00'';
IF (@DOSYA = 'KYCEKNODB_2') THEN SELECT @SONUC = NEWSERINO FROM KYCEKNODB_2 WHERE NEWSERINO=''223 99 00'';
gibi kullansanız?
Kullanıcı avatarı
naile
Admin
Mesajlar: 1873
Kayıt: 11 Haz 2003 10:11

Mesaj gönderen naile »

Şu şekilde yapabilirsiniz:

Kod: Tümünü seç

SET @SQLKOMUTU ='SELECT NEWSERINO FROM '+@DOSYA +' WHERE NEWSERINO=''223 99 00''' 
EXEC sp_executesql @SQLKOMUTU
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mesaj gönderen ofenX »

Merhaba,
naile yazdı:

Kod: Tümünü seç

SET @SQLKOMUTU ='SELECT NEWSERINO FROM '+@DOSYA +' WHERE NEWSERINO=''223 99 00''' 
EXEC sp_executesql @SQLKOMUTU
Naile Hanım dikkat ederseniz. Ben de

Kod: Tümünü seç

exec(@sqlkomutu)
ile istediğimi alabiliyorum. Ama ben o çıkan sonucu @sonuc değişkenine atamayı bilmiyorum. Bu konuda yardımcı olabilirseniz.
Not :

Kod: Tümünü seç

 exec (@sqlkomutu) 
ile

Kod: Tümünü seç

EXEC sp_executesql @SQLKOMUTU
arasında belirgin bir fark var mı? Hangisini kullanmamı tavsiye edersiniz?
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
Kullanıcı avatarı
naile
Admin
Mesajlar: 1873
Kayıt: 11 Haz 2003 10:11

Mesaj gönderen naile »

Pardon yanlış anlamışım,

Kod: Tümünü seç

DECLARE @NEWSERI
SET @SQLKOMUTU ='SELECT '+@NEWSERI+'=NEWSERINO FROM '+@DOSYA +' WHERE NEWSERINO=''223 99 00'''
EXEC sp_executesql @SQLKOMUTU
SELECT @NEWSERI
İki kodun arasında da fark var mı bilmiyorum açıkcası, ben o şekilde kullandığımdan onu yazmıştım :)
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mesaj gönderen ofenX »

Merhaba Naile Hanım,
verdiğiniz kodu,

Kod: Tümünü seç

DECLARE @NEWSERI VARCHAR (16)
DECLARE @SQLKOMUTU VARCHAR(500)
DECLARE @DOSYA VARCHAR(500)
SET @DOSYA='KYCEKNODB'

SET @SQLKOMUTU ='SELECT '+@NEWSERI+'=NEWSERINO FROM '+@DOSYA +' WHERE NEWSERINO=''223 99 00'''
EXEC sp_executesql @SQLKOMUTU
SELECT @NEWSERI
şeklinde denedim.
Yürütmede hata:
Procedure expects parameter '@statement' of type 'ntext/nchar/nvarchar'.
şeklinde bir hata verdi.
Son iki satırı satırı silip.

Kod: Tümünü seç

select @sqlkomutu
bana NULL değer döndürüyor.
Bir yerde yanlışlık yapıyorum. Ama nerede?
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
Kullanıcı avatarı
naile
Admin
Mesajlar: 1873
Kayıt: 11 Haz 2003 10:11

Mesaj gönderen naile »

varchar yerine nvarchar kullanman gerekiyor.

Kod: Tümünü seç

DECLARE @SQLKOMUTU NVARCHAR(500) 


Senin kodunu şu şekilde değiştirip denedin mi?

Kod: Tümünü seç

declare @DOSYA VARCHAR(255)
DECLARE @SQLKOMUTU VARCHAR(4000)
DECLARE @SONUC VARCHAR(16)

SET @DOSYA='KYCEKNODB'
SET @SQLKOMUTU ='SELECT '+@SONUC+'=NEWSERINO FROM '+@DOSYA +' WHERE NEWSERINO=''223 99 00'''
EXEC (@SQLKOMUTU) 
SELECT @SONUC
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mesaj gönderen ofenX »

Merhaba Naile Hanım,

Sizin bana verdiğiniz örneği denemiş miydiniz? Çünkü bana ilk gönderdiğinizde

Kod: Tümünü seç

SET @SQLKOMUTU ='SELECT '+@SONUC+'=NEWSERINO 
komutundan şüpheliydim.
Dediğiniz gibi nvarchar şekline dönüştürdüm.Hatta

Kod: Tümünü seç

SET @SQLKOMUTU =N'SELECT '+@SONUC+'=NEWSERINO FROM '+@DOSYA +' WHERE NEWSERINO=''223 99 00''' 
şeklinde de kullandım. Yine olmadı. Yine

Kod: Tümünü seç

select @sqlkomutu 
şeklinde yapınca bana null değer döndürdü.
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
Kullanıcı avatarı
naile
Admin
Mesajlar: 1873
Kayıt: 11 Haz 2003 10:11

Mesaj gönderen naile »

Denemeden yaptıklarımdan ezbere gidip cevap yazınca böyle arada birsürü laf kalabalığı oluşturdum kusura bakma. Şimdi uygulama yaptım, ilk verdiğin gibi EXEC(@SQLKOMUTU) satırından sonra şu kodu yazarsanız sonucu değişkeninize alabiliyorsunuz:

Kod: Tümünü seç

SET @SONUC=@@ROWCOUNT

kolay gelsin.
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mesaj gönderen ofenX »

Merhaba,
naile yazdı:

Kod: Tümünü seç

SET @SONUC=@@ROWCOUNT
cevabınız için teşekkür ederim.(Ben @@rowcount u cevabınızda görünce satır sayısı için kullanıldığını sanıyordum. ) Programın hepsini yazıp buraya atayım dedim. Ama yine sorunlar çıktı.
Çünkü değişken dosya isimlerini fonksiyon ve cursor tanımlarında kullanamadım. Başka mesaj atacağıma buradan devam edeyim dedim.
Benim yapmak istediklerimi
Inline Table-valued Functions

CREATE FUNCTION [ owner_name. ] function_name
( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] )

RETURNS TABLE

[ WITH < function_option > [ [,] ...n ] ]

[ AS ]

RETURN [ ( ] select-stmt [ ) ]
ve
Transact-SQL Extended Syntax
DECLARE cursor_name CURSOR
[ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]
karşılıyor.
İki fonksiyon yapmayı düşünmüştüm. Birincisinde RETURNS TABLE ile kayıtlara ulaşmayı düşünüyordum.
İkinci fonksiyonda ise

Kod: Tümünü seç

FETCH ABSOLUTE @SIRA FROM KY_CUR INTO @DEGER
ile istediğim satır numarasını alacaktım. Bunları değişkensiz olarak alabiliyorum.

Şimdi sorumuza gelelim. sql textini bir değişkene alıp yukarıdaki fonksiyonlarda kullanabilir miyiz?


Kod: Tümünü seç

create function kycekno (@deneme int)
returns table
 exec sp_executesql N'select * from KYCEKNODB'

......
gibi bir şeyi kabul etmiyor.

Aynı şekilde cursor un FOR deyiminden sonra da yukarıdaki gibi exec i kullanamıyorum. Yani exec veya alternatifi kullanılabilir mi?
Bu konuda bilgisi olan varsa yardımlarınızı bekliyorum.

İyi çalışmalar.
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
Kullanıcı avatarı
naile
Admin
Mesajlar: 1873
Kayıt: 11 Haz 2003 10:11

Mesaj gönderen naile »

Logoda bizim de en çok sıkıntı çektiğimiz konu tabloların isimlendirmesi. Her devir döneminde aynı db içinde tablo isimlerini firma no ve döneme göre değiştirmesi işlerimizi biraz zorlaştırıyor. Halbuki netsisde db değiştiği halde tablo isimleri aynı kaldığı için pek bir sorun yaşamıyorduk. Gerçi logoda da bu özellik varmış ama çalıştığım şirkette diğeri kullanılıyor.

Logo kendisi her devir sırasında tablo isimlerini değiştirdiği gibi kullandığı stored procedure, triggerların da yenisini oluşturuyor. Yani sizin yapmaya çalıştığınız dinamik bir yapıyı logonun kendisi de kullanmamış aslında. Biz ne yapıyoruz peki? :) Anlatayım: Biz program içinde yazdığımız sql stringleri ansireplacetext kullanarak yeni firma ve döneme göre replace yapıyoruz. Ama işte sql tarafındaki view, procedure v.b.lerde sorunlar yaşıyoruz. Bizim düşündüğümüz yöntem yine devir esnasında yazacağımız bir programcık ile kulandığımız tüm objelerdeki gerekli replaceleri yapmak yönünde idi. Ama bu da çok sağlıklı olmayabiliyor çünkü herzaman sadece dönem değişmiyor, firma da değişebiliyor ve biz sadece çalıştığımız dönemi değil bir önceki hatta iki önceki dönemi bile sorgularımızda kullanmış olabiliyoruz. Bu da çok karışıklığa neden olduğundan,tam sene sonuna da gelmişken, sanırım sql server tarafına manuel bir çözüm getireceğiz. Sizin yapmaya çalıştığınız yöntem de aslında kullanım açısından baya dinamik olacak ama işte bu şekilde yapılabilir mi bilmiyorum. Çünkü sql serverda yapmakta zorluk çektiğim hatta yapmama izin vermediği şeylerle karşılaşıyorum, bu da o tür birşey olabilir mi acaba diye düşündüm ben maalesef.

Bukadar yazıdan sonra yapmaya çalıştığınız şeye çözüm getirememiş olmak çok kötü ama hiç değilse karşılıklı fikir beyanında bulunmuş olduk :) hem belki bu sorunlarımıza cevap verecek birisi çıkar.

Kolay gelsin.
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mesaj gönderen ofenX »

Merhaba Naile Hanım,
Öncelikle bana sorulan soruyu açmakla işe başlayayım.
Lks de borç takip olayı var. Bu borç takibinde Örneğin
BD14675 nolu alış faturasını seçip bu fatura 1563,1564,1565 seri nolu çeklerle ödenmiştir diyebiliyorsunuz. Ama borç takip ekranında sadece çek senedin fiş nosu görünüyor. Vatandaşın satıcı firması geldiğinde BD14675 nolu faturamızı ödememişsiniz dediğinde. Adam "bd14675 nolu faturanın hangi çeklerle ödendiğini göreyim" diyor.

Ben de tablo yapılarına baktım.

Kod: Tümünü seç

SELECT NEWSERINO 
FROM
LG_200_01_CSCARD AS A,
LG_200_01_CSTRANS AS B,
LG_200_01_PAYTRANS AS      C,
LG_200_01_INVOICE AS       D, 
LG_200_01_PAYTRANS AS      E

WHERE 

D.FICHENO='0000000000000003'  AND D.TRCODE=1 AND 
C.FICHEREF=D.LOGICALREF AND C.CLOSINGRATE=1   AND C.TRCODE=1 AND C.MODULENR=4 AND 
E.LOGICALREF=C.CROSSREF AND E.CLOSINGRATE=1 AND E.TRCODE=3 AND E.MODULENR=6 AND 
B.ROLLREF= E.FICHEREF AND B.LOGICALREF=E.FICHELINEREF AND 
A.LOGICALREF=B.CSREF 


şeklinde alabildiğimi görebiliyorum.

Lks tarafında ise Adama diyeceğim ki"Sen alış faturasının üzerine geleceksin. örneğin bd14675 nolu faturanın üzerindeyken sağ tıklayıp yaz seçeneğini seçeceksin. Yazıcı yerine ekranı seçeceksin. Sana dökecek. "
yukarıdaki deyimi iki fonksiyon ile lksden alabiliyorum.
Lks de kullanıcı tanımlı bir alan yapıp. bu çek numaralarını alabiliyorum.
Sonucu alış faturasının yaz kısmını alarak sizin bahsettiğiniz firma no ve dönem nolarının sorununu halletmiş oluyorum. Oradan direk fişno, dönem no , firma no bilgilerini kullanıcı girmemiş oluyor.
Lks tarafında _sqlinfo fonksiyonunu biraz yanıltarak istediğimi alıyorum.
Kullanıcı tanımlı alan tipini Metin yapıp formül kısmına

Kod: Tümünü seç

_sqlinfo ("LKSDB.DBO.kysilana('"+[fis]+"',3)","L_BANKCODE","LOGICALREF=2")
yazıyorum. Şuan sadece fiş numarasını vererek 200 nolu firmanın 01 nolu dönemi için yukarıdaki şekilde alabiliyorum. Fişten sonraki 3 rakamı
3. sıradaki serinoyu ver anlamındadır.
Bu şekilde 10 tane kullanıcı tanımlı alan yapıp 3 yerine sıra numarasına göre uygun bilgileri girecektim.

Şu an manuel olarak her şey hazır. Sadece yapmak istediğim.
kursor tanımlamada ve create funtion un return table kısmında
exec sp_executesql ile stringimi çalıştıramıyorum.
Yada daha da değiştireyim fonksiyonun için de de exec komutunu kullanamıyorum.
Bu konuda bilgisi olan varsa yardımlarınızı bekliyorum.
ofenX yazdı:

Kod: Tümünü seç

 exec (@sqlkomutu) 
ile

Kod: Tümünü seç

EXEC sp_executesql @SQLKOMUTU 
arasında belirgin bir fark var mı? Hangisini kullanmamı tavsiye edersiniz?
İkisinin arasındaki farkı msdn yi karıştırırken buldum.

Kod: Tümünü seç

Execute a character string:

EXEC [ UTE ] ( { @string_variable | [ N ] 'tsql_string' } [ + ...n ] ) 
 
ile düz bir deyim işletebiliyorsunuz. Ama

Kod: Tümünü seç

sp_executesql [@stmt =] stmt
[ 
    {, [@params =] N'@parameter_name  data_type [,...n]' } 
    {, [@param1 =] 'value1' [,...n] }
]

ile parametre içeren deyimler oluşturabiliyorsunuz.

Kod: Tümünü seç


declare @dosya    varchar(500)
declare @deyim nvarchar(4000)
declare @faturano varchar(16)
declare @belge_nu varchar(16)
set @faturano='0000000000000003'
set @belge_nu='BD14675'




set @dosya ='LG_200_01_INVOICE'

set @deyim=N'select * from '+@dosya+' where FICHENO=@fisno and DOCODE=@belgeno'
                          
exec sp_executesql @deyim, 
                                  N'@fisno varchar(16), @belgeno varchar(16)',
                                    @fisno=@faturano,
                                       @belgeno=@belge_nu
                         

şeklinde bir örnek verebiliriz.

Herkese iyi çalışmalar dilerim.
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mesaj gönderen ofenX »

Merhaba,
Arkadaşın istediğini Lks altından çalışacak şekilde yapamadım. Çünkü mssql bir fonksiyon içinden bir stored procedure çalıştırmaya izin vermiyor. Onun sorununu Vtyonet programında çalışacak bir stored procedure yaparak hallettim.

Kod: Tümünü seç

create procedure KYCEKNO @FIS_NO VARCHAR(16),@FIRMA VARCHAR(3),@DONEM VARCHAR(3)
AS
BEGIN
DECLARE @DOSYAA   VARCHAR(100)
DECLARE @DOSYAB   VARCHAR(100)
DECLARE @DOSYAC   VARCHAR(100)
DECLARE @DOSYAD   VARCHAR(100)
DECLARE @DOSYAE   VARCHAR(100)
DECLARE @SQLKOMUTU NVARCHAR(4000)

SET @DOSYAA='LG_'+@FIRMA+'_'+@DONEM+'_CSCARD'
SET @DOSYAB='LG_'+@FIRMA+'_'+@DONEM+'_CSTRANS'
SET @DOSYAC='LG_'+@FIRMA+'_'+@DONEM+'_PAYTRANS'
SET @DOSYAD='LG_'+@FIRMA+'_'+@DONEM+'_INVOICE'
SET @DOSYAE='LG_'+@FIRMA+'_'+@DONEM+'_PAYTRANS'

SET @SQLKOMUTU=N'SELECT A.NEWSERINO  FROM '
+@DOSYAA+' AS A,  '
+@DOSYAB+' AS B,  '
+@DOSYAC+' AS C,  '
+@DOSYAD+' AS D,  '
+@DOSYAE+' AS E'
+' WHERE  D.FICHENO=@FICH_NUMARASI  AND D.TRCODE=1 AND  C.FICHEREF=D.LOGICALREF AND C.CLOSINGRATE=1   AND C.TRCODE=1 AND C.MODULENR=4 AND E.LOGICALREF=C.CROSSREF AND E.CLOSINGRATE=1 AND E.TRCODE=3 AND E.MODULENR=6 AND B.ROLLREF= E.FICHEREF AND B.LOGICALREF=E.FICHELINEREF AND A.LOGICALREF=B.CSREF  '

EXEC sp_executesql @SQLKOMUTU,
N'@FICH_NUMARASI  VARCHAR(16)',@FICH_NUMARASI=@FIS_NO

END

Hiç yoktan iyidir. :lol: :lol: :lol:

Herkese kolay gelsin.
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
Cevapla