SQL查询字符串在SQL Server Management Studio中有效,但在VB.net中不能通过SQLCommand.ExecuteReader使用

问题描述 投票:0回答:1

我有一个使用VB.net代码的ASPX页面,并且将其设置为运行一系列SQL查询并使用结果填充SQLDataReader。每个SQL查询都是从SQL数据库中表的特定字段中提取的。这段代码实际上适用于我所执行的每个查询,但其中一个除外。

涉及的VB代码如下。

Dim SQL_Template_Query As String
Dim cmd3 As SqlCommand = New SqlCommand
Dim r3 As SqlDataReader    

cmd3 = New SqlCommand(SQL_Template_Query)
cmd3.CommandTimeout = 1200 ' Extended to 1200 sec = 20 min
cmd3.CommandType = CommandType.Text
cmd3.Connection = Global_Objects.SQLLocalDB_Connection
Try
    r3 = Nothing
    r3 = cmd3.ExecuteReader() ' THIS LINE IS WHERE THE ERROR OCCURS
Catch
    Session("Main_Error_Code") = 1
    Session("Main_Error_Message") = "The SQL statement for the following address is invalid. Please examine the GCDB_Excel_Reports_Templates record, and correct." &
                    Chr(13) & "ID " & ti.ID & ", " & ti.Sheet_Name & ", " & ti.Cell_Address

    ' Write to error log
    cxlErrorsSheetLog.Cell("A" & cxlErrorsCurRow).Value = Session("Main_Error_Message")
    cxlErrors.SaveAs(cxlErrorsPath)
    cxlErrors = Nothing
    cxlDoc = Nothing
    Return
End Try

如您所见,我已经有了捕获错误的代码,所以我确切地知道错误发生在哪里,但是我不确定为什么。当

时发生错误

SQL_Template_Query =“ DECLARE @Start_Year int; SET @ Start_Year = 2018; DECLARE @Reporting_Year int; SET @ Reporting_Year = 2021;声明@First_Year int; set @ First_Year =(((@ Reporting_Year- @ Start_Year + 1)的情况<= 5,然后@Start_Year else @Reporting_Year-4结束);删除表(如果存在)#Reporting_Years;创建表#Reporting_Years(Reporting_Year int);插入到#Reporting_Years中,从Single_Date中选择不同的YEAR(Single_Date),其中@Reporting_Year之间的YEAR(Single_Date) -4和@Reporting_Year;删除表(如果存在)#Has_ACT;创建表#Has_ACT(Building_ID int,Start_Date datetime,End_Date datetime);插入到#Has_ACT中,从Tracking_Periods中选择不同的Building_ID,MIN(Start_Date),MAX(End_Date),其中Utility_Type_ID在16和19以及YEAR(Start_Date)<= @ Reporting_Year和(YEAR(End_Date)> = @ First_Year或End_Date为空)按Building_ID分组;选择i1.Reporting_Year, SUM(当i2.Asset_Class类似于“ Office”时为GFA否则为空端)作为Office_GFA,SUM(当i2.Asset_Class类似于“ Retail”时为GFA否则为空端)作为Retail_GFA,SUM(当i2.Asset_Class如“ Industrial”时为S2) ',然后是GFA,否则为空端)作为#Reporting_Years i1左连接中的Industrial_GFA(选择z1.Reporting_Year,x.Building_ID,y.Building,y.Asset_Class,x.Start_Year,x.End_Year,y.Most_Recent_GFA_Year,如果是z1.Reporting_Year <= y.Most_Recent_GFA_Year然后(从Annual_GFA中选择GFA,其中Building_ID = x.Building_ID和Reporting_Year = z1.Reporting_Year),否则(从Annual_GFA中选择GFA,其中Building_ID = x.Building_ID和Reporting_Year = y.Most_Recent_GFFA_Year选择GFA(从年终) ,当YEAR(Start_Date) @ Reporting_Year然后@Reporting_Year然后@Reporting_Year则@Reporting_Year,否则YEAR(End_Date)作为End_End从#Has_ACT开始的年份)x左连接(从View_All_Buildings_Annual_GFA的Most_Recent_GFA_Year中选择a.Building_ID,a.Building,a.Asset_Class,MAX(a.Reporting_Year),在a.Building_ID = b。 c.Building_ID = a.Building_ID和c.Reporting_Year=@Reporting_Year内部联接Building_Ownership d在a.Building_ID = d.Building_ID左联接Override_Building_Count e在a.Building_ID = e.Building_ID和e.Report_ID = 5内部联接#Has_ACT f f.Building_ID = a.Building_ID,其中b.Asset_Manager类似于“匿名”,b.Not_On_Program = 0,b.Exclude_From_Reporting = 0,b.Tenant = 0,d.Year_Removed为null,并且(e.Building_Count <> 0或e。 Building_Count为null)通过x.Building_ID = y.Building_ID交叉连接按#Building_ID,a.Building,a.Asset_Class y分组#Reporting_Years z1,其中@First_Year和@Reporting_Year之间的z1.Reporting_Year和z1.Repo rting_Year> = x.Start_Year和z1.Reporting_Year <= x.End_Year和y.Building_ID不为null)i2在i1.Reporting_Year = i2.Reporting_Year上,其中i1.Reporting_Year在@Start_Year和@Reporting_Year组之间按i1.Reporting_Year的顺序排列.Reporting_Year; “

我按原样提供字符串,以防任何人想知道VB.net如何解析它。此查询对开发人员更友好的解析如下所示。

DECLARE @Start_Year int;
SET @Start_Year=2018;
DECLARE @Reporting_Year int;
SET @Reporting_Year=2021;

declare @First_Year int;
set @First_Year =  
(  
case   
when (@Reporting_Year-@Start_Year+1)<=5 then @Start_Year   
else @Reporting_Year - 4 end  
);       

drop table if exists #Reporting_Years;       

create table #Reporting_Years  
(
Reporting_Year int
);   

insert into #Reporting_Years 
select distinct YEAR(Single_Date) 
from Single_Dates where YEAR(Single_Date) 
between @Reporting_Year-4 and @Reporting_Year;   

drop table if exists #Has_ACT;   

create table #Has_ACT (Building_ID int,Start_Date datetime,End_Date datetime);   

insert into #Has_ACT  
select distinct Building_ID,MIN(Start_Date),MAX(End_Date)  from Tracking_Periods  
where Utility_Type_ID between 16 and 19 
and YEAR(Start_Date)<=@Reporting_Year  
and (YEAR(End_Date)>=@First_Year or End_Date is null)  
group by Building_ID;     

select i1.Reporting_Year,  
SUM(case when i2.Asset_Class like 'Office' then GFA else null end) as Office_GFA,  
SUM(case when i2.Asset_Class like 'Retail' then GFA else null end) as Retail_GFA,  
SUM(case when i2.Asset_Class like 'Industrial' then GFA else null end) as Industrial_GFA  
from #Reporting_Years i1  
left join
(
select z1.Reporting_Year,x.Building_ID,y.Building,y.Asset_Class,x.Start_Year,x.End_Year,y.Most_Recent_GFA_Year,  
case  when z1.Reporting_Year<=y.Most_Recent_GFA_Year   
then 
(select GFA from Annual_GFA where Building_ID=x.Building_ID and Reporting_Year=z1.Reporting_Year)  
else 
(select GFA from Annual_GFA where Building_ID=x.Building_ID and Reporting_Year=y.Most_Recent_GFA_Year)
end as GFA  
from   
(  
select Building_ID,  
case  
when YEAR(Start_Date)<@First_Year then @First_Year  
else YEAR(Start_Date) end as Start_Year,  
case  
when End_Date is null then @Reporting_Year  
when YEAR(End_Date)>@Reporting_Year then @Reporting_Year  
else YEAR(End_Date) end as End_Year from #Has_ACT) x  
left join   
(
select a.Building_ID,a.Building,a.Asset_Class,MAX(a.Reporting_Year) as Most_Recent_GFA_Year  
from View_All_Buildings_Annual_GFA a      
inner join View_All_Buildings b on a.Building_ID=b.Building_ID      
inner join View_All_Building_Ownership_By_Year c on c.Building_ID=a.Building_ID and c.Reporting_Year=@Reporting_Year      
inner join Building_Ownership d on a.Building_ID=d.Building_ID      
left join Override_Building_Count e on a.Building_ID=e.Building_ID and e.Report_ID=5      
inner join #Has_ACT f on f.Building_ID=a.Building_ID    
where b.Asset_Manager like 'Anonymous'      
and b.Not_On_Program=0 and b.Exclude_From_Reporting=0 and b.Tenant=0      
and d.Year_Removed is null    
and (e.Building_Count<>0 or e.Building_Count is null)  
group by a.Building_ID,a.Building,a.Asset_Class) y on x.Building_ID=y.Building_ID  
cross join #Reporting_Years z1 where z1.Reporting_Year between @First_Year and @Reporting_Year  
and z1.Reporting_Year>=x.Start_Year and z1.Reporting_Year<=x.End_Year  
and y.Building_ID is not null) i2 on i1.Reporting_Year=i2.Reporting_Year  
where i1.Reporting_Year between @Start_Year and @Reporting_Year  
group by i1.Reporting_Year  
order by i1.Reporting_Year;  

当我在SQL Server Management Studio中运行此查询时,一个又一个字符地返回了我期望的结果。

enter image description here

但是,当VB代码运行时,它会触发捕获代码。阅读过类似问题的帖子后,我尝试将查询修改为产生0而不是NULL,但是问题仍然存在。另外,其他查询会产生NULL值,但可以与VB代码一起正常工作。

任何建议将不胜感激。我也想知道是否有办法让SQLDataAdapter或SQLCommand返回错误。这将使事情更容易诊断。

UPDATE:如果我注释掉Try ... Catch ... End Try,并允许Visual Studio生成错误,则会收到以下消息。

enter image description here

sql sql-server vb.net sqldatareader sqlcommand
1个回答
0
投票
代码现在可以按预期工作。仍然不清楚为什么这个特定的SQL语句导致了问题,而其他原因却没有。但是,无论如何,我将重做该项目中的所有代码以移出单个连接对象。

@ AndrewMorton其他评论中提供的链接,https://ubitsoft.com/t-sql-beautilyzer/也很有帮助。实际上,我一直在寻找一种无需基础数据库即可独立检查SQL查询的方法。

© www.soinside.com 2019 - 2024. All rights reserved.