レコードの DataTable を返すことになっている VS2010 .Net 4.0 Web サービスがあります。今日までうまく機能していたようです。SQL Server Management Studio を介して 5 つのパラメーター (3 つの int と 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 経由で実行すると、1 つしか取得できません (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~テオ~2008-02-13 00:00:00.000~0~0 ~Shar Pei~Short~Apricot~White~Male~Unknown~cccccccc~~kkkkkkk~4444 RICHLAND AVE.~~xxxxxx~~OH~44444~5555555~Home~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 ~ラブラドールレトリバー~ミディアム~ブラック~不明~男性~Ms~xxxxx~~xxxxxxxx~4444 GIEL AVE~~xxxxxx~~OH~44444~5555555~ホーム~xxxxxx~個人
これはかなり奇妙です。あなたの教祖の一人が私を助けてくれることを願っています.
解決策: SQL プロファイラの提案について @EJBrennan に感謝します。これまで使用したことはありませんでしたが、正しい方向に向けてくれました。実際に SQL に送信されていたのは次のとおりです。
exec FetchLicenseReceiptData @ForYear=2013,@StartNumber=270,@EndNumber=271,@StartDate='2012-01-01 00:00:00',@EndDate='2012-12-13 00:00:00'
それを実行すると、2行ではなく1行になりました。基本的に、時間の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 は、渡された日付の 1 日後です。
ありがとう@EJBrennan