0

我有一个 VS2010 .Net 4.0 Web 服务,它应该返回记录的 DataTable。直到今天,它似乎一直运行良好。如果我通过 SQL Server Management Studio 将 5 个参数(3 个整数和 2 个日期时间)传递给它,我会得到我期望的所有行。但是,当我通过服务运行并检查 ds.Fill(MyTable) 行上的变量时,某些行不会显示。

我刚刚注意到一些奇怪的事情,当我搜索 TagNumber 1-270 的项目时,我得到了 SSMS 和 .Fill 中的所有行。每当我尝试返回 TagNumbers 介于 271 和 300 之间的项目时,所有这些行都会显示在 SSMS 中,但它们都不会在 .Fill 中返回。我检查过的所有 300 多件作品都符合预期。

这是我的存储过程。我能说的并不特别。

ALTER PROCEDURE [dbo].[FetchLicenseReceiptData] (
    @ForYear INT,
    @StartNumber INT,
    @EndNumber INT,
    @StartDate DATETIME,
    @EndDate DATETIME
)
AS
BEGIN
-- Also update udf GetLicenseReceiptData

SELECT
    DISTINCT
    -- License Fields
    l.BarCode,
    l.TagNumber,
    l.Issued,
    l.ForYear,
    l.Fee,
    l.WebOrderNumber,
    lts.Name AS TagStyle,
    CAST(CAST((l.ForYear + 1) AS VARCHAR) + '-01-31' AS DATETIME) AS RenewalDate,
    -- Dog Fields
    d.Name AS DogName,
    d.BirthDate,
    d.SpayNeuter,
    d.Deceased,
    lb.Name AS Breed,
    lhl.Name AS HairLength,
    lpc.Name AS PrimaryColor,
    lsc.Name AS SecondaryColor,
    lx.Name AS Sex,
    -- Owner Fields
    lt.Name AS Title,
    o.FirstName,
    o.Initial,
    o.LastName,
    -- Address Fields
    a.Address1,
    a.Address2,
    a.City,
    a.County,
    ls.Abbreviation AS State,
    a.ZipCode,
    -- Contact Fields
    jpi.PhoneNumber AS PrimaryPhoneNumber,
    jpi.PhoneType AS PrimaryPhoneType,
    jei.EmailAddress AS PrimaryEmail,
    jei.EmailType AS PrimaryEmailType
FROM
                    data.License      AS   l
    LEFT OUTER JOIN data.Dog          AS   d ON l.DogID = d.ID
    LEFT OUTER JOIN data.Owner        AS   o ON d.OwnerID = o.ID
    LEFT OUTER JOIN data.Address      AS   a ON o.AddressID = a.ID
    LEFT OUTER JOIN lookup.Title      AS  lt ON o.TitleID = lt.ID
    LEFT OUTER JOIN lookup.State      AS  ls ON a.StateID = ls.ID
    LEFT OUTER JOIN lookup.TagStyle   AS lts ON l.TagStyleID = lts.ID
    LEFT OUTER JOIN lookup.Breed      AS  lb ON d.BreedID = lb.ID
    LEFT OUTER JOIN lookup.HairLength AS lhl ON d.HairLengthID = lhl.ID
    LEFT OUTER JOIN lookup.Color      AS lpc ON d.PrimaryColorID = lpc.ID
    LEFT OUTER JOIN lookup.Color      AS lsc ON d.SecondaryColorID = lsc.ID
    LEFT OUTER JOIN lookup.Sex        AS  lx ON d.SexID = lx.ID
    LEFT OUTER JOIN (
        SELECT
            p.Number AS PhoneNumber,
            lpt.Name AS PhoneType,
            op.OwnerID AS OwnerID
        FROM
                            data.OwnerPhone  AS  op
            LEFT OUTER JOIN data.Phone       AS   p ON op.PhoneID = p.ID
            LEFT OUTER JOIN lookup.PhoneType AS lpt ON p.PhoneTypeID = lpt.ID
        WHERE
            p.IsPrimary = 1
    ) AS jpi ON o.ID = jpi.OwnerID
    LEFT OUTER JOIN (
        SELECT
            e.Address AS EmailAddress,
            let.Name AS EmailType,
            oe.OwnerID AS OwnerID
        FROM
                            data.OwnerEmail  AS  oe
            LEFT OUTER JOIN data.Email       AS   e ON oe.EmailID = e.ID
            LEFT OUTER JOIN lookup.EmailType AS let ON e.EmailTypeID = let.ID
        WHERE
            e.IsPrimary = 1
    ) AS jei ON o.ID = jei.OwnerID
WHERE
        l.ForYear = @ForYear
    AND l.TagNumber >= @StartNumber
    AND l.TagNumber <= @EndNumber
    AND l.Issued >= @StartDate
    AND l.Issued <= @EndDate
ORDER BY
    l.TagNumber

结尾

在这里结束是我调用 SP 的方法:

    public DataTable FetchLicenseReceiptData(int ForYear, int StartNumber, int EndNumber, DateTime StartDate, DateTime EndDate) {
        DataTable Result = new DataTable();

        try {
            using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DogLicensingContext"].ConnectionString)) {
                SqlCommand cmd = new SqlCommand("FetchLicenseReceiptData", con);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(new SqlParameter("@ForYear", ForYear));
                cmd.Parameters.Add(new SqlParameter("@StartNumber", StartNumber));
                cmd.Parameters.Add(new SqlParameter("@EndNumber", EndNumber));
                cmd.Parameters.Add(new SqlParameter("@StartDate", StartDate));
                cmd.Parameters.Add(new SqlParameter("@EndDate", EndDate));

                con.Open();

                SqlDataAdapter ds = new SqlDataAdapter(cmd);
                ds.Fill(Result);
                Result.TableName = "LicenseReceiptDataAutoPrint";
            } // using the connection
        } catch (Exception e) {

        } // try-catch

        return Result;
    } // FetchLicenseReceiptData - Method

所以在 SSMS 中,当我运行以下命令时:

FetchLicenseReceiptData 2013, 270, 271, '2012-01-01', '2012-12-31'

我得到2条记录。通过 .Fill 运行时,我只得到一个(270)

当我在 SSMS 中运行以下命令时:

FetchLicenseReceiptData 2013, 271, 300, '2012-01-01', '2012-12-31'

我得到了所有 30 行。但是通过 .Fill 它不会返回任何内容。

最后,如果我运行以下命令:

FetchLicenseReceiptData 2013, 301, 310, '2012-01-01', '2012-12-31'

我在 SSMS 和 .Fill 中都得到了 10 个。

作为返回数据的示例,这里是 SSMS 中返回的 270 和 271 数据。我用波浪号 (~) 字符替换了选项卡

01CA2013T000270~270~2012-12-12 16:10:58.273~2013~20.00~NULL~标准~2014-01-31 00:00:00.000~Theo~2008-02-13 00:00:00.000~0~0 ~沙皮~短~杏~白~男~未知~cccccccc~~kkkkkkk~4444 RICHLAND AVE.~~xxxxxx~~OH~44444~5555555~家~NULL~NULL

01CA2013T000271~271~2012-12-13 08:44:58.670~2013~20.00~NULL~标准~2014-01-31 00:00:00.000~SAMSON~1999-12-12 00:00:00.000~1~0 ~拉布拉多犬~中~黑色~未知~男~女士~xxxxx~~xxxxxxxxxx~4444 GIEL AVE~~xxxxxx~~OH~44444~5555555~家~xxxxxx~个人

这个很奇怪。希望你们中的一位大师可以帮助我。

解决方案: 感谢@EJBrennan 的 SQL Profiler 建议。我以前从未使用过它,但它为我指明了正确的方向。这是实际上被发送到 SQL:

exec FetchLicenseReceiptData @ForYear=2013,@StartNumber=270,@EndNumber=271,@StartDate='2012-01-01 00:00:00',@EndDate='2012-12-13 00:00:00'

当我运行它时,它给了我 1 行而不是 2 行。基本上除了 00:00:00 之外的值是相同的。我最终将以下内容添加到我的存储过程的顶部以强制事情正确:

SET @StartDate = DATEADD(DAY, DATEDIFF(DAY, 0, @StartDate), 0) -- Beginning of given Date
SET @EndDate   = DATEADD(DAY, DATEDIFF(DAY, 0, @EndDate),   1) -- End of given Date

这将获取传入的任何 @StartDate 并将其强制为当天的 0:0:0。然后它将@EndDate 设置为NEXT 日期,同时设置时间为0:0:0。

同样在 WHERE 子句中 SP 的底部,我将 <= @EndDate 更改为 < EndDate 从现在开始,@EndDate 是传入日期之后的一天。

再次感谢@EJBrennan

4

0 回答 0