【问题标题】:Different Result of JSP executeQuery() and MSMS in the same queriesJSP executeQuery() 和 MSMS 在同一查询中的不同结果
【发布时间】:2018-04-11 22:36:51
【问题描述】:

我正在使用 tomcat、jsp 和 MSSQL 2008,并且想要获取一些汇总数据,例如 Daily、Weekly、Monthly 和 Yearly。 从这里,我搜索了如何将 datapart() 函数用于这些来自 MSSQL 的摘要数据。 在 JSP 中,我使用了

PreparedStatement pr = conn.prepareStatement(query);
ResultSet rs=pr.executeQuery();

在 MSMS 中,查询目录进行测试。

我在 JSP 程序中遇到了两个问题,但在 MS SQL Server Management Studio 中使用相同的查询运行良好。

This is a screenshot of query result in MSMS

我的问题是:

  • “每年”的查询在 JSP 中不起作用。
  • 在查询“每月”时,不返回月份值(1,2,3,...) 正确,但只有 0(零)。

“每日”和“每周”运行良好。我该如何解决这些问题? 提前致谢。

我的查询是:

switch (unit)
{
    case "Daily"        :
        query = "SELECT cast(datepart(dy, ProcessDate) as varchar(3)) Day, " + 
                    "cast(year(ProcessDate) as varchar(4)) Year, " + 
                    "SUM(case WHEN Warranty = 'Y' then 1 else 0 end) InWarranty, " + 
                    "SUM(case WHEN Warranty = 'N' then 1 else 0 end) OutOfWarranty, " +
                    "SUM(case WHEN Warranty = 'X' then 1 else 0 end) NAWarranty " +
                    "FROM zz_RMA_Summary " +
                    "WHERE ProcessDate BETWEEN '" + sDate + "' AND '" + eDate + "' " +
                    "group by year(ProcessDate), datepart(dy, ProcessDate) " +
                    "order by year(ProcessDate) DESC, datepart(dy, ProcessDate) DESC ";
        break;

    case "Weekly"       :   
        query = "SELECT cast(datepart(wk, ProcessDate) as varchar(2)) Week, " + 
                    "cast(year(ProcessDate) as varchar(4)) Year, " + 
                    "SUM(case WHEN Warranty = 'Y' then 1 else 0 end) InWarranty, " + 
                    "SUM(case WHEN Warranty = 'N' then 1 else 0 end) OutOfWarranty, " +
                    "SUM(case WHEN Warranty = 'X' then 1 else 0 end) NAWarranty " +
                    "FROM zz_RMA_Summary " +
                    "WHERE ProcessDate BETWEEN '" + sDate + "' AND '" + eDate + "' " +
                    "group by year(ProcessDate), datepart(wk, ProcessDate) " +
                    "order by year(ProcessDate) DESC, datepart(wk, ProcessDate) DESC ";
        break;

    case "Monthly"      :
        query = "SELECT cast(datepart(mm, ProcessDate) as varchar(2)) Month, " + 
                    "cast(year(ProcessDate) as varchar(4)) Year, " + 
                    "SUM(case WHEN Warranty = 'Y' then 1 else 0 end) InWarranty, " + 
                    "SUM(case WHEN Warranty = 'N' then 1 else 0 end) OutOfWarranty, " +
                    "SUM(case WHEN Warranty = 'X' then 1 else 0 end) NAWarranty " +
                    "FROM zz_RMA_Summary " +
                    "WHERE ProcessDate BETWEEN '" + sDate + "' AND '" + eDate + "' " +
                    "group by year(ProcessDate), datepart(mm, ProcessDate) " +
                    "order by year(ProcessDate) DESC, datepart(mm, ProcessDate) DESC ";
        break;

    case "Yearly"       :
        query = "SELECT cast(yyyyy, ProcessDate) as varchar(4)) Year, " + 
                    "SUM(case WHEN Warranty = 'Y' then 1 else 0 end) InWarranty, " + 
                    "SUM(case WHEN Warranty = 'N' then 1 else 0 end) OutOfWarranty, " +
                    "SUM(case WHEN Warranty = 'X' then 1 else 0 end) NAWarranty " +
                    "FROM zz_RMA_Summary " +
                    "WHERE ProcessDate BETWEEN '" + sDate + "' AND '" + eDate + "' " +
                    "group by datepart(yyyy, ProcessDate) " +
                    "order by datepart(yyyy, ProcessDate) DESC ";
        break;
}  

【问题讨论】:

    标签: java sql-server jsp


    【解决方案1】:

    您的问题是由您传递为stringsdates 引起的,这是错误的。

    为什么要用动态sql,是强制的吗?

    你可以将它与parametersdate 类型)一起使用,而不是与string 连接吗?

    如果你坚持你的字符串连接,你应该使用convert() 使用适当样式的函数来传递您的日期字符串,或者,以yyyymmdd 格式传递您的日期,不带任何分隔符,这将为您带来一致的结果。

    现在发生的情况是,或者您的应用程序以另一种格式提供 dates,而不是您在 SSMS 中使用的格式,或者您的应用程序只是使用了另一个 login,它具有不同的 default language

    登录的默认语言随后由会话继承,它会影响日期常量的解释方式。

    这是一个例子:

    declare @t table (dt datetime);
    insert into @t values ('20170110'), ('20171001'); -- Jan, 10; Oct, 1st
    
    set language british -- this happens when my login's default language is us_english 
    select *
    from @t 
    where dt between '01/09/2017' and '01/01/2018' -- I'm in Europe an I want the dates starting from Sept, 1st 
    ---
    dt
    2017-10-01 00:00:00.000 -- I'm happy with correct result
    
    
    
    set language us_english -- this happens when my login's default language is us_english 
    select *
    from @t 
    where dt between '01/09/2017' and '01/01/2018' -- I'm in Europe an I want the dates starting from Sept, 1st 
    ----
    dt
    2017-01-10 00:00:00.000 -- quite strange since I filtered starting from September
    2017-10-01 00:00:00.000
    

    但是,如果您使用between '20170901' and '20180101' 而不是between '01/09/2017' and '01/01/2018',则这一切都不会发生,即yyyymmdd

    【讨论】:

    • 谢谢你,sepupic。你的建议不是决定性的,但它让我得到了答案。在“月度”和“年度”部分,JSP 中有一些错误的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多