Prosedur tersimpan Transact-SQL dengan logika kondisional DAN

Saya sedang mengerjakan prosedur tersimpan yang digunakan untuk memfilter kisi berdasarkan kriteria yang dimasukkan oleh pengguna. Di antara kriteria yang mungkin, mereka dapat memilih untuk melihat transaksi yang dilakukan antara tanggal mulai dan akhir tertentu. Saya meneruskan 4 parameter input ke proc - @ClientKey, klien yang meminta info, @FilterBy (ini adalah nilai yang dipilih dari daftar dropdown di ASP.NET, dan pada dasarnya memberi tahu proc apakah pengguna memilih untuk memfilter berdasarkan nama, alamat, tanggal, dll. Dalam hal ini nilai @FilterBy untuk tanggal adalah 5), @Value1, yang dalam hal ini adalah tanggal mulai, dan @Value2, yang dalam hal ini adalah tanggal akhir.

Dalam kode semu, yang saya inginkan adalah:

PILIH ABunchOfColumns DARI SomeJoinedTables WHERE SomeCriteria AND CASE @FilterBy WHEN 5 MAKA d.TransactionTime >= CAST(@Value1 AS Date) DAN d.TransactionTime ‹= CAST(@Value2 AS Date)

Di bawah ini adalah pertanyaan lengkapnya. Saya berharap seseorang yang lebih paham dari saya dengan SQL dapat memahami apa yang saya coba lakukan dan menawarkan solusi.

Terima kasih sebelumnya!

@ClientKey  int,
@FilterBy   int,
@Value1 varchar(150),
@Value2 varchar(150)

SEBAGAI MULAI

SELECT d.pKey AS PaymentKey, d.CaseKey, d.InvoiceID, d.AuthorizationCode, d.TransactionID, d.PaymentType, d.Amount, d.ExpirationDate, d.CardType, d.BankName, d.AccountNumber, 
    d.AccountType, c.Name, c.Address1, c.City, c.State, c.Zip, cs.PAmount, cs.TranCode, cs.TranDate, cs.[Desc] AS PaymentDescription, cc.[Desc] AS ChargeCodeDescription,
    d.TransactionTime, a.Name AS AssociationName, d.PaymentType, c.ClientPaymentID
FROM DebtorPayment d INNER JOIN Cases c
    ON d.CaseKey = c.pKey
    AND d.ClientKey = c.ClientKey
INNER JOIN CaseSumm cs
    ON d.CaseKey = cs.CaseKey
    AND d.pKey = cs.Batch
    AND d.ClientKey = cs.ClientKey
INNER JOIN ChargeCodes cc
    ON c.ClientKey = cc.ClientKey
    AND cs.TranCode = cc.RefNum
INNER JOIN AssnCtrl a
    ON c.AssnKey = a.pKey
WHERE c.ClientKey = @ClientKey
AND d.AmountAllocated > 0
AND d.TransactionStatus = 'Successful' 
AND c.Address1 LIKE CASE
    WHEN @FilterBy = 1 THEN '%' + @Value1 + '%'
    ELSE c.Address1
    END
AND d.Amount = CASE
    WHEN @FilterBy = 2 THEN @Value1
    ELSE d.Amount
    END  
AND a.pKey = CASE
    WHEN @FilterBy = 3 THEN CAST(@Value1 AS INT)
    ELSE a.pKey
    END
AND c.ClientPaymentID = CASE
    WHEN @FilterBy = 4 THEN @Value1
    ELSE c.ClientPaymentID
    END 
<ProblemArea>
AND CASE @FilterBy
        WHEN 5 THEN d.TransactionTime >= CAST(@Value1 AS Date) AND d.TransactionTime <= CAST(@Value2 AS Date)
    END
</ProblemArea>
AND c.LName LIKE CASE
    WHEN @FilterBy = 6 THEN '%' + @Value1 + '%'
    ELSE c.LName
    END
ORDER BY d.TransactionTime DESC

AKHIR


person Mike    schedule 08.05.2014    source sumber


Jawaban (2)


Maksudnya seperti berikut ini? Anda mungkin menemukan tautan ini juga berguna. Belum menguji kodenya, hanya mengajukan ide - dan menulis kode seperti ini selalu terasa "salah" bagi saya - mungkin ada yang bisa menawarkan lebih baik.

CREATE PROC MyProc

    @ClientKey  int,
    @FilterBy   int,
    @Value1 varchar(150),
    @Value2 varchar(150)
--  NB WITH RECOMPILE, see link (above)
WITH RECOMPILE AS
BEGIN
    SET NOCOUNT ON;

    SELECT *
    FROM ...
    WHERE 
        Col1    =   CASE 
                        WHEN @FilterBy = 1 THEN @Value1
                        ELSE Col1
                    END
    AND
        1       =   CASE
                        WHEN @FilterBy = 2 AND Col2 > @Value1 AND Col3 < @Value2        THEN 1
                        WHEN @FilterBy = 2 AND NOT (Col2 > @Value1 AND Col3 < @Value2)  THEN 0
                        ELSE 1
                    END 
END
person MarkD    schedule 08.05.2014

person    schedule
comment
atau.. KASUS KETIKA @FilterBy = 5 AND d.TransactionTime BETWEEN CAST(@Value1 AS DATE) AND CAST(@Value2 AS DATE) THEN 1 ELSE 0 END = 1 Bekerja dengan cara yang sama, namun di antara membuat kode lebih mudah dibaca. Itu hanya preferensi pribadi, tidak ada perbedaan dalam pelaksanaannya. - person Richard Vivian; 11.05.2014
comment
Sebenarnya saya hanya mengujinya sebentar sebelum harus menyelesaikan peningkatan sistem lainnya. Sekarang saya kembali ke sini, sepertinya proc tidak mengembalikan baris apa pun untuk dan nilai @FilterBy selain 5. Tidak yakin mengapa. - person Mike; 16.05.2014
comment
untuk *setiap nilai @FilterBy selain 5. - person Mike; 16.05.2014
comment
@Mike Saya hanya fokus pada bagian area masalah di mana Anda berada. Tampaknya Anda perlu menggunakan AND ((First @FilterBy) OR (Second @FilterBy) OR ....). Bagaimanapun, saya tidak meninjau semua filter tersebut - person Lamak; 16.05.2014
comment
Terima kasih Lamak - pahami cakupan fokusnya. Belum ada kebahagiaan, tapi masih berusaha. - person Mike; 16.05.2014