My Current SQL语法类似于
Declare CursorName CURSOR FOR
Select Query
现在,select查询将包含If-Else Condition。
If @Parameter1 is NULL
BEGIN
Select-Query1
END
ELSE
BEGIN
Select-Query2
END
如何在SQL Server中的游标内写入第二个If-Else语句?
请帮忙! 让我知道我的意见。!!
我的原始查询
Create Table #TempTable(PlanID BIGINT,PlanName NVARCHAR(50),InsuranceCompany Nvarchar(100),CurrentBalance DECIMAL(14,2),
[30DaysBalance] DECIMAL(14,2),[60DaysBalance] DECIMAL(14,2),[90DaysBalance] Decimal(14,2),
[120DaysBalance] DECIMAL(14,2),[150DaysBalance] Decimal(14,2),CurrentDaysPlanAmount DECIMAL(14,2),
[30DaysPlanAmount] DECIMAL(14,2),[60DaysPlanAmount] DECIMAL(14,2),[90DaysPlanAmount] Decimal(14,2),
[120DaysPlanAmount] DECIMAL(14,2),[150DaysPlanAmount] Decimal(14,2),StartDate DateTime,EndDate DateTime
)
BEGIN
Declare @BillID BIGINT,@PatientID BIGINT,@BillDetailID BIGINT,@SendDt DateTime
Declare Cursor_Claim_PlanAgingReport Cursor
For Select Bill.BillID,Bill.PatientID,BillDetail.BillDetailID,Claim.SendDt From Bill Inner Join
BillDetail On Bill.BillID = BillDetail.BillID Inner Join
Claim on Bill.BillID = Claim.BillID Left Outer Join
Payment On Bill.BillID = Payment.BillID
Where
---Payment.BillID Is Null AND
Claim.SendDt
Between @StartDt AND @EndDt
---And Claim.Status = 'Sent'
AND Claim.Status = 'Resent'
Open Cursor_Claim_PlanAgingReport
FETCH NEXT FROM Cursor_Claim_PlanAgingReport INTO @BillID,@PatientID,@BillDetailID,@SendDt
While @@FETCH_STATUS = 0
BEGIN
Insert Into #TempTable SELECT Distinct(vwAgingPlan.PlanID),vwAgingPlan.Plan_Name,vwAgingPlan.Insurance_Company,
--// Current Balance --
IsNull((SELECT top 1 vwAgingPlan.Copay as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) < 30 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID), 0) AS CurrentBalance,
--// [30DaysBalance] --
IsNull((SELECT top 1 vwAgingPlan.Copay as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) > 30 AND DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) <= 60 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID), 0) AS [30DaysBalance],
--// [60DaysBalance] --
IsNull((SELECT top 1 vwAgingPlan.Copay as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) > 60 AND DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) <= 90 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID), 0) AS [60DaysBalance],
--// [90DaysBalance] --
IsNull(
(SELECT top 1vwAgingPlan.Copay as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) > 90 AND DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) <= 120 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID), 0) AS [90DaysBalance],
--// [120DaysBalance] --
IsNull((SELECT top 1 vwAgingPlan.Copay as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) > 120 AND DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) <= 150 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID), 0) AS [120DaysBalance],
--// [150DaysBalance] --
IsNull((SELECT top 1 vwAgingPlan.Copay as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.SendDt,getDate()) > 150 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID), 0) AS [150DaysBalance],
IsNull((SELECT top 1 vwAgingPlan.PlanAmount as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.CreatedDt,getdate()) <= 30 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID),0) AS CurrentDaysPlanAmount,
IsNull((SELECT top 1 vwAgingPlan.PlanAmount as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.CreatedDt, getdate()) > 30 AND DATEDIFF("dd", vwAgingPlan.CreatedDt,getdate()) <= 60 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID),0) AS [30DaysPlanAmount],
IsNull((SELECT top 1 vwAgingPlan.PlanAmount as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.CreatedDt, getdate()) > 60 AND DATEDIFF("dd", vwAgingPlan.CreatedDt,getdate()) <= 90 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID),0) AS [60DaysPlanAmount],
IsNull((SELECT top 1 vwAgingPlan.PlanAmount as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.CreatedDt, getdate()) > 90 AND DATEDIFF("dd", vwAgingPlan.CreatedDt,getdate()) <= 120 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID),0) AS [90DaysPlanAmount],
IsNull((SELECT top 1 vwAgingPlan.PlanAmount as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.CreatedDt, getdate()) > 120 AND DATEDIFF("dd", vwAgingPlan.CreatedDt,getdate()) <= 150 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID),0) AS [120DaysPlanAmount],
IsNull((SELECT top 1 vwAgingPlan.PlanAmount as s from vwAgingPlan WHERE DATEDIFF("dd", vwAgingPlan.CreatedDt, getdate()) > 150 And vwAgingPlan.BillID = @BillID And vwAgingPlan.PatientID = @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID), 0) AS [150DaysPlanAmount] ,
@StartDt,@EndDt
FROM
vwAgingPlan
WHERE
vwAgingPlan.BillID = @BillID AND vwAgingPlan.PatientID= @PatientID AND vwAgingPlan.BillDetailID = @BillDetailID
FETCH NEXT FROM Cursor_Claim_PlanAgingReport INTO @BillID,@PatientID,@BillDetailID,@SendDt
END
Close Cursor_Claim_PlanAgingReport
Deallocate Cursor_Claim_PlanAgingReport
Select * From #TempTable
END
我的If-Else查询
IF @InsuranceName IS NULL
BEGIN
SELECT Bill.BillID,
Bill.PatientID,
BillDetail.BillDetailID,
Claim.SendDt,
Claim.SendDT,
InsurancePlan.Name
FROM Bill
INNER JOIN BillDetail
ON Bill.BillID = BillDetail.BillID
INNER JOIN Claim
ON Bill.BillID = Claim.BillID
INNER JOIN Payment
ON Bill.BillID = Payment.BillID
INNER JOIN dbo.InsurancePlan
ON dbo.BillDetail.PlanID = dbo.InsurancePlan.InsurancePlanID
INNER JOIN dbo.InsuranceCompany
ON dbo.InsurancePlan.InsuranceCompID = dbo.InsuranceCompany.InsuranceCompID
WHERE
Claim.SendDt BETWEEN @StartDt AND @EndDt
AND Claim.Status = 'Resent'
--OR Claim.Status = 'Resent'
PRINT 'No Insurance Name'
END
ELSE
BEGIN
SELECT Bill.BillID,
Bill.PatientID,
BillDetail.BillDetailID,
Claim.SendDt,
Claim.SendDT,
Claim.[Status],
Payment.BillId AS PaymentBillID,
InsurancePlan.Name
FROM Bill
INNER JOIN BillDetail
ON Bill.BillID = BillDetail.BillID
INNER JOIN Claim
ON Bill.BillID = Claim.BillID
INNER JOIN Payment
ON Bill.BillID = Payment.BillID
INNER JOIN dbo.InsurancePlan
ON dbo.BillDetail.PlanID = dbo.InsurancePlan.InsurancePlanID
INNER JOIN dbo.InsuranceCompany
ON dbo.InsurancePlan.InsuranceCompID = dbo.InsuranceCompany.InsuranceCompID
WHERE InsurancePlan.Name = @InsuranceName
--AND Payment.BillID IS NULL
AND Claim.SendDt BETWEEN @StartDt AND @EndDt
AND Claim.[Status]='Resent'
PRINT 'Insurance Name: ' + @InsuranceName
END
答案 0 :(得分:11)
和 HATE 游标一样多,试试这个:
DECLARE @FetchColumn varchar(10)
If @Parameter1 is NULL
BEGIN
DECLARE YourCursor CURSOR FOR
SELECT
Column1
FROM YourTable
WHERE ...
FOR READ ONLY
END
ELSE
BEGIN
DECLARE YourCursor CURSOR FOR
SELECT
ColumnB
FROM YourTable
WHERE ...
FOR READ ONLY
END
--populate and allocate resources to the cursor
OPEN YourCursor
--process each row
WHILE 1=1
BEGIN
FETCH NEXT FROM YourCursor
INTO @FetchColumn
--finished fetching all rows?
IF @@FETCH_STATUS <> 0
BEGIN --YES, all done fetching
--exith the loop
BREAK
END --IF finished fetching
--do something here--
--do something here--
PRINT @FetchColumn
END --WHILE
--close and free the cursor's resources
CLOSE YourCursor
DEALLOCATE YourCursor
从您的代码中看起来您有动态搜索条件。具有动态搜索条件的关键是确保使用索引,而不是如何轻松地重用代码,消除查询中的重复,或尝试使用相同的查询执行所有操作。这是一篇关于如何处理这个主题的非常全面的文章:
Dynamic Search Conditions in T-SQL by Erland Sommarskog
它涵盖了尝试使用多个可选搜索条件编写查询的所有问题和方法。您需要关注的主要问题不是代码的重复,而是索引的使用。如果您的查询无法使用索引,那么它将执行不良。有几种技术可以使用,可能允许也可能不允许使用索引。
这是目录:
Introduction The Case Study: Searching Orders The Northgale Database Dynamic SQL Introduction Using sp_executesql Using the CLR Using EXEC() When Caching Is Not Really What You Want Static SQL Introduction x = @x OR @x IS NULL Using IF statements Umachandar's Bag of Tricks Using Temp Tables x = @x AND @x IS NOT NULL Handling Complex Conditions Hybrid Solutions – Using both Static and Dynamic SQL Using Views Using Inline Table Functions Conclusion Feedback and Acknowledgements Revision History
如果您使用的是适当版本的SQL Server 2008,则可以使用其他技术,请参阅:Dynamic Search Conditions in T-SQL Version for SQL 2008 (SP1 CU5 and later)
如果您使用的是SQL Server 2008的正确版本,则只需将OPTION (RECOMPILE)
添加到查询中,并在运行时将局部变量的值用于优化。
考虑到这一点,OPTION (RECOMPILE)
将采用此代码(其中没有索引可用于此OR
的混乱):
WHERE
(@search1 IS NULL or Column1=@Search1)
AND (@search2 IS NULL or Column2=@Search2)
AND (@search3 IS NULL or Column3=@Search3)
并在运行时优化它(假设只有@ Search2传入了一个值):
WHERE
Column2=@Search2
并且可以使用索引(如果在Column2上定义了一个索引)
答案 1 :(得分:0)
我会更改游标的主SELECT,以便它使用CASE语句和表变量来设置一个char字段,该字段将每个记录标记为某种类型。
例如:
DECLARE @Stuff TABLE
(
ID int IDENTITY (1, 1) PRIMARY KEY NOT NULL,
SystemID int,
Flag char
)
INSERT INTO @Stuff (SystemID, Flag)
SELECT
SystemID,
CASE SomeFieldInMainTable
WHEN 1 THEN 'A'
WHEN 2 THEN 'B'
WHEN 3 THEN 'C'
ELSE 0
END
FROM TheTable
这将允许您创建您正在使用游标逐步执行的任何表的子集,并根据适用于您的子查询的CASE逻辑“标记”该子集中的记录,但您只需要使用一个大的SELECT而不是IF块中的单独的。
填充表变量后,您可以单独查询它以获取从主表中提取的所需数据。