none
Sql While Döngüsü Problem? RRS feed

  • Soru

  • Arkadaşlar hazırladığım sql fonksiyonunda while döngüsü kullandım.Ve şöyle birşey yapıyor.Bir tarih veriyorum o tarihteki döviz kurunu çekiyor verdiğim tarihte döviz kuru yoksa bir sonraki tarihe gidip o döviz kurunu almasını istiyorum bir sonraki tarihte te yoksa diğer günü almasını istiyorum yani bulana kadar devam etmesini istiyorum ama fonksiyon çalışmıyor hata veriyor sebebi de bazı tarihlerde döviz kuru yok olmadığı için bir sonraki tarihe gitmiyor direk hata veriyor acaba nerede hata yaptım bakabilir misiniz?

    CREATE FUNCTION [dbo].[fn_DovizKuru]
    (@Tarih AS Int,
    @Kur AS Tinyint) 
    RETURNS Money AS BEGIN 
    DECLARE @i INT,
    @gelen MONEY,
    @durum BIT
    
    SET @i = 0 
    SET @gelen=0 
    SET @durum=1 
    
    WHILE (@durum=1) 
    BEGIN SET @gelen=
    (SELECT  (CASE  @Kur   
    WHEN 1 THEN  DVZ002_DvzAlis1 
    WHEN 2 THEN  DVZ002_DvzSatis1 
    WHEN 3 THEN  DVZ002_DvzAlis2 
    WHEN 4 THEN  DVZ002_DvzSatis2 
    WHEN 5 THEN  DVZ002_DvzAlis3 
    WHEN 6 THEN  DVZ002_DvzSatis3 
    WHEN 7 THEN  DVZ002_DvzAlis4 
    WHEN 8 THEN  DVZ002_DvzSatis4 END) AS DovizKuru  
    FROM DVZ002 WHERE DVZ002_DovizDate=@tarih-@i) 
    
    IF @gelen is null  
    BEGIN SET @i = @i +1
    END 
    ELSE 
    BREAK  
    END 
    RETURN @gelen END

    19 Aralık 2013 Perşembe 07:30

Yanıtlar

  • Sql Server programlarken koşullu döngüleri eğer gerçekten daha uygun bir çözüm yoksa kullanmanızı öneririm.

    Sizin fonksiyonunuzda da While döngüsünü kaldırarak döngüsel işlemi sorgu içine gömmek dolayısıyla veritabanı motoruna bu işi yüklemek mümkün.

    Fonksiyonu aşağıdaki hale getirdiğinizde parametre olarak verilen tarihe eşit veya en yakın tarihteki kur okunacağından sorunun çözüleceğini düşünüyorum.

    CREATE FUNCTION [dbo].[fn_DovizKuru]
    (@Tarih int, @Kur tinyint)
    RETURNS money
     AS
    BEGIN 
    DECLARE
     @gelen money = 0;
    
    SELECT @gelen = ( CASE @Kur
    WHEN 1 THEN DVZ002_DvzAlis1 WHEN 2 THEN DVZ002_DvzSatis1
    WHEN 3 THEN DVZ002_DvzAlis2 WHEN 4 THEN DVZ002_DvzSatis2
    WHEN 5 THEN DVZ002_DvzAlis3 WHEN 6 THEN DVZ002_DvzSatis3
    WHEN 7 THEN DVZ002_DvzAlis4 WHEN 8 THEN DVZ002_DvzSatis4
    END )
    FROM DVZ002
    WHERE DovizDate = ( SELECT MAX(DovizDate) FROM DVZ002 WHERE DovizDate <= @Tarih )
    ;
    RETURN @gelen
    END
    GO

    Tarih tiplerinin veritabanında sayısal olarak saklandığı doğru olsa da bu tipte verileri işlemek için int tipini seçmeniz çok kısıtlayıcı bir seçim olmuş. Yine de tercih sizin tabi..

    19 Aralık 2013 Perşembe 21:32

Tüm Yanıtlar

  • @Tarih Date tipinden olması gerekmiyormu ? 

    Microsoft bu servisi kullanıcılarına yardım etme, Microsoft urunleri ve teknolojileriyle ilgili bilgi bankasını genişletme amacıyla ucretsiz sunmaktadır. Bu icerik olduğu gibi benim tarafımdan hazırlanmış olup Microsoft tarafından herhangi bir sorumluluk ustlenildiği anlamına gelmez. Iletişim: barissaritas[at]windowslive[nokta]com

    19 Aralık 2013 Perşembe 07:33
  • int olarak kaydediyor problem yok o konuda excel de böyle kaydediyor.tarih 41565 gibi geliyor mesela
    19 Aralık 2013 Perşembe 07:44
  • Sql Server programlarken koşullu döngüleri eğer gerçekten daha uygun bir çözüm yoksa kullanmanızı öneririm.

    Sizin fonksiyonunuzda da While döngüsünü kaldırarak döngüsel işlemi sorgu içine gömmek dolayısıyla veritabanı motoruna bu işi yüklemek mümkün.

    Fonksiyonu aşağıdaki hale getirdiğinizde parametre olarak verilen tarihe eşit veya en yakın tarihteki kur okunacağından sorunun çözüleceğini düşünüyorum.

    CREATE FUNCTION [dbo].[fn_DovizKuru]
    (@Tarih int, @Kur tinyint)
    RETURNS money
     AS
    BEGIN 
    DECLARE
     @gelen money = 0;
    
    SELECT @gelen = ( CASE @Kur
    WHEN 1 THEN DVZ002_DvzAlis1 WHEN 2 THEN DVZ002_DvzSatis1
    WHEN 3 THEN DVZ002_DvzAlis2 WHEN 4 THEN DVZ002_DvzSatis2
    WHEN 5 THEN DVZ002_DvzAlis3 WHEN 6 THEN DVZ002_DvzSatis3
    WHEN 7 THEN DVZ002_DvzAlis4 WHEN 8 THEN DVZ002_DvzSatis4
    END )
    FROM DVZ002
    WHERE DovizDate = ( SELECT MAX(DovizDate) FROM DVZ002 WHERE DovizDate <= @Tarih )
    ;
    RETURN @gelen
    END
    GO

    Tarih tiplerinin veritabanında sayısal olarak saklandığı doğru olsa da bu tipte verileri işlemek için int tipini seçmeniz çok kısıtlayıcı bir seçim olmuş. Yine de tercih sizin tabi..

    19 Aralık 2013 Perşembe 21:32