【问题标题】:Select records for two tables where any parameter can be empty选择任何参数可以为空的两个表的记录
【发布时间】:2016-04-19 17:25:17
【问题描述】:

我正在使用 SQL Server 2008,并使用 C# 进行开发。我刚开始一个星期。并坚持这种情况。我有两张桌子

表 1

EMID    EMNA        EMCN
---------------------------
1       Junaid      1347609
2       Jhon        1347610
3       Shwan       1347611
4       ABC         1347612

表 2

EMCN        ALDT        ALTM
--------------------------------
1347609     12/21/2015  52:00.0
1347609     12/21/2015  30:00.0
1347610     12/21/2015  50:00.0
1347610     12/22/2015  30:00.0
1347611     12/23/2015  50:00.0
1347611     12/21/2015  43:00.0
1347609     12/30/2015  25:00.0
1347611     12/29/2015  13:00.0
1347611     12/28/2015  43:00.0
1347609     12/27/2015  24:00.0
1347610     12/26/2015  03:00.0

需要的输出:

    EMNA    ALDT        ALTM
    -------------------------
    Junaid  30-Dec-2015 16:25
    Jhon    29-Dec-2015 20:13
    Shawn   28-Dec-2015 06:43
    Junaid  27-Dec-2015 15:24
    Jhon    26-Dec-2015 10:03
    Shawn   23-Dec-2015 11:50
    Jhon    22-Dec-2015 13:30
    Junaid  21-Dec-2015 09:30
    Jhon    21-Dec-2015 18:50
    Junaid  21-Dec-2015 14:52
    Shawn   21-Dec-2015 09:43

用户可以选择多个员工和日期范围,任何字段都可以为空,在 SQL Server 中此查询返回结果,但在 C# 中我无法获得结果。问题在于IN(),如果没有选择用户,即EMID 为空白,它应该返回所选日期范围的所有记录。如果选择了一个日期,则应仅返回该日期的结果

SQL 查询

Declare @EMID int;
Declare @FromDate date;
Declare @ToDate date;

if @FromDate is null
   SET @FromDate = @ToDate;

if @ToDate is null
   SET @ToDate = @FromDate;

Select  
    E.EMNA,  
    REPLACE(LEFT(CONVERT (varchar, c.ALDT, 106),11),' ','-') AS ALDT,  
    CONVERT(VARCHAR(5),c.ALTM , 108) AS ALTM 
from 
    Table1 E 
join
    Table2 C on E.EMCN = C.EMCN
where
    (E.EMID IN(@EMID) OR @EMID IS NULL) 
    and (c.ALDT > @FromDate OR @FromDate IS NULL) 
    and (c.ALDT < dateadd(day,1,@ToDate) OR @ToDate IS NULL)
order by  
    C.ALDT DESC

SQL 字符串

string strSqlQuery = string.Format(@"    
Declare @EMID int;
Declare @FromDate date;
Declare @ToDate date;
SET @EMID = {0};
SET @FromDate = '{1}';

if @FromDate is null
   SET @FromDate = @ToDate;

SET @ToDate = '{2}';

if @ToDate is null
   SET @ToDate = @FromDate;

Select  
    E.EMNA,  
    REPLACE(LEFT(CONVERT (varchar, c.ALDT, 106),11),' ','-') AS ALDT,  
    CONVERT(VARCHAR(5),c.ALTM , 108) AS ALTM 
from 
    A01001 E 
join 
    A01008 C on E.EMCN = C.EMCN
where
    (E.EMID IN(@EMID) OR @EMID IS NULL) 
    and (c.ALDT > @FromDate OR @FromDate IS NULL) 
    and (c.ALDT < dateadd(day, 1, @ToDate) OR @ToDate IS NULL)
order by
    Y C.ALDT DESC", 
    objCabinet.strEmployeeId, strFromDate,objCabinet.strToDate);

如何修复此查询或我的字符串以使其适用于以下场景

  • 选择了多名员工,但未选择日期范围
  • 根据日期范围选择了多个员工
  • 一个日期选择了多个员工

我创建了一个存储过程,但它没有返回值。

存储过程:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[sptEmpCabAccess]
     @EMID int = null,
     @FromDate date = null,
     @ToDate date = null
AS
BEGIN
    IF (@FromDate IS NULL)
        SET @FromDate = @ToDate;

    IF (@ToDate IS NULL)
        SET @ToDate = @FromDate;

    Select  
        E.EMNA,  
        REPLACE(LEFT(CONVERT (varchar, c.ALDT, 106),11),' ','-') AS ALDT,  
        CONVERT(VARCHAR(5),c.ALTM , 108) AS ALTM 
    from 
        A01001 AS E 
    join
        A01008 AS C on E.EMCN = C.EMCN
    where
        (E.EMID IN(@EMID) OR @EMID IS NULL) 
        and (c.ALDT > @FromDate OR @FromDate IS NULL) 
        and (c.ALDT < dateadd(day,1,@ToDate) OR @ToDate IS NULL)
    order by
        C.ALDT DESC
    END
GO

调用存储过程的C#代码:

using (SqlConnection objsqlconn = new SqlConnection(conn))
{
    objsqlconn.Open();

    try
    {
        using (SqlCommand objcmd = new SqlCommand("sptEmpCabAccess", objsqlconn))
        {
            objcmd.CommandType = CommandType.StoredProcedure;

            objcmd.Parameters.Add("@EMID", SqlDbType.Int).Value = objCabinet.strEmployeeId;
            objcmd.Parameters.Add("@FromDate", SqlDbType.Date).Value = objCabinet.strFromDate; ;
            objcmd.Parameters.Add("@ToDate", SqlDbType.Date).Value = objCabinet.strToDate;

            // error here cannot implicitly convert type 'int' to 'system.data.dataset'
            dsGetData = objcmd.ExecuteNonQuery();
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

【问题讨论】:

  • 你知道如何使用存储过程吗?这在 C# 中是绝对不行的。
  • 我创建了一个但它没有返回值,更新了问题
  • objCabinet.strFromDate,objCabinet.strToDate 值为NULLABLE
  • 如果您的查询有效,您的 SP 也应该有效。你能公布你的SP的代码吗?还有您编写的用于调用 SP 的 C# 代码。
  • 完成,存储过程和cSharp代码都添加了,是的值是NULLABLE

标签: c# sql asp.net sql-server database


【解决方案1】:

您需要更改应用过滤器的查询,而不是使用 Null 进行检查,并分配一些默认值,例如

1) 声明@EMID int=0;

2) 在哪里 (E.EMID IN(@EMID) 或 @EMID=0)

【讨论】:

  • 删除其他日期过滤器进行测试,然后运行 ​​WHERE (E.EMID =@EMID OR @EMID=0)。这一定是工作试一试。
  • 没有与此ID关联的记录怎么办,我试过但没有结果
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-19
  • 1970-01-01
相关资源
最近更新 更多