ขั้นตอนการจัดเก็บ Transact-SQL พร้อมเงื่อนไขและตรรกะ

ฉันกำลังดำเนินการขั้นตอนการจัดเก็บที่ใช้ในการกรองกริดตามเกณฑ์ที่ผู้ใช้ป้อน ในเกณฑ์ที่เป็นไปได้ พวกเขาอาจเลือกที่จะดูธุรกรรมที่เกิดขึ้นระหว่างวันที่เริ่มต้นและวันที่สิ้นสุดที่แน่นอน ฉันส่งพารามิเตอร์อินพุต 4 ตัวไปยัง proc - @ClientKey ไคลเอนต์ร้องขอข้อมูล @FilterBy (นี่คือค่าที่เลือกจากรายการดรอปดาวน์ใน ASP.NET และโดยพื้นฐานแล้วจะบอก proc ว่าผู้ใช้เลือกที่จะกรองตามชื่อหรือไม่ ที่อยู่ วันที่ ฯลฯ ในกรณีนี้ ค่า @FilterBy สำหรับวันที่คือ 5), @Value1 ซึ่งในกรณีนี้จะเป็นวันที่เริ่มต้น และ @Value2 ซึ่งในกรณีนี้จะเป็นวันที่สิ้นสุด

ในรหัสเทียมสิ่งที่ฉันต้องการคือ:

เลือก ABunchOfColumns จาก SomeJoinedTables โดยที่ SomeCriteria และ CASE @FilterBy WHEN 5 THEN d.TransactionTime >= CAST(@Value1 AS Date) AND d.TransactionTime ‹= CAST(@Value2 AS Date)

ด้านล่างนี้คือคำถามแบบเต็ม ฉันหวังว่าคนที่เชี่ยวชาญ SQL มากกว่าฉันจะสามารถแยกแยะสิ่งที่ฉันพยายามทำและเสนอวิธีแก้ปัญหาได้

ขอบคุณล่วงหน้า!

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

เหมือนเริ่มต้น

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

จบ


person Mike    schedule 08.05.2014    source แหล่งที่มา


คำตอบ (2)


คุณหมายถึงบางสิ่งที่คล้ายกันต่อไปนี้หรือไม่? คุณอาจพบว่าลิงก์นี้มีประโยชน์เช่นกัน ยังไม่ได้ทดสอบโค้ด แค่เสนอไอเดีย - และการเขียนโค้ดแบบนี้ทำให้ฉันรู้สึกว่า "ผิด" มาตลอด - บางทีอาจมีบางคนเสนอข้อเสนอที่ดีกว่านี้ได้

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
หรือ.. CASE WHEN @FilterBy = 5 AND d.TransactionTime BETWEEN CAST(@Value1 AS DATE) AND CAST(@Value2 AS DATE) THEN 1 ELSE 0 END = 1 ทำงานเหมือนกัน แต่ระหว่างทำให้โค้ดอ่านง่ายขึ้น นั่นเป็นเพียงความชอบส่วนบุคคล ไม่มีความแตกต่างในการดำเนินการ - person Richard Vivian; 11.05.2014
comment
จริงๆ แล้ว ฉันทดสอบสิ่งนี้เพียงช่วงสั้นๆ ก่อนที่จะต้องดำเนินการปรับปรุงระบบอื่นให้เสร็จสิ้น ตอนนี้ฉันกลับมาที่นี่อีกครั้ง ดูเหมือนว่า proc จะไม่ส่งคืนแถวใด ๆ สำหรับและค่า @FilterBy นอกเหนือจาก 5 ไม่แน่ใจว่าทำไม - person Mike; 16.05.2014
comment
สำหรับ *ค่า @FilterBy ใดๆ ที่ไม่ใช่ 5 - person Mike; 16.05.2014
comment
@ ไมค์ฉันเน้นเฉพาะในส่วนปัญหาของคุณเท่านั้น ดูเหมือนว่าคุณจะต้องใช้ AND ((First @FilterBy) OR (Second @FilterBy) OR ....) ไม่ว่าในกรณีใด ฉันไม่ได้ตรวจสอบตัวกรองเหล่านั้นทั้งหมด - person Lamak; 16.05.2014
comment
ขอบคุณ Lamak - เข้าใจขอบเขตที่มุ่งเน้น ยังไม่มีความสุขแต่ก็ยังพยายามอยู่ - person Mike; 16.05.2014