我在使用内连接计算数据时遇到问题。
我想算一下有多少小屋,这是我的桌子:
这是我在课堂上获取山寨号的代码。
public void CheckCottages()
{
con.Close();
SqlCommand comUmbrella = new SqlCommand("CountCottages", con);
comUmbrella.CommandType = CommandType.StoredProcedure;
comUmbrella.Parameters.Add("@CottageType", SqlDbType.NVarChar).Value = "Umbrella";
comUmbrella.Parameters.Add("@ReservedDate", SqlDbType.DateTime).Value = this.ARRIVAL;
con.Open();
comUmbrella.ExecuteNonQuery();
drUmbrella = comUmbrella.ExecuteReader();
if (drUmbrella.Read())
{
this.UMBRELLA = drUmbrella.GetInt32(drUmbrella.GetOrdinal("Rows"));
}
con.Close();
SqlCommand comNativeKubo = new SqlCommand("CountCottages", con);
comNativeKubo.CommandType = CommandType.StoredProcedure;
comNativeKubo.Parameters.Add("@CottageType", SqlDbType.NVarChar).Value = "Native Kubo";
comNativeKubo.Parameters.Add("@ReservedDate", SqlDbType.DateTime).Value = this.ARRIVAL;
con.Open();
comNativeKubo.ExecuteNonQuery();
drKubo = comNativeKubo.ExecuteReader();
if (drKubo.Read())
{
this.NATIVEKUBO = drKubo.GetInt32(drKubo.GetOrdinal("Rows"));
}
con.Close();
SqlCommand comTreeHouse = new SqlCommand("CountCottages", con);
comTreeHouse.CommandType = CommandType.StoredProcedure;
comTreeHouse.Parameters.Add("@CottageType", SqlDbType.NVarChar).Value = "Tree house";
comTreeHouse.Parameters.Add("@ReservedDate", SqlDbType.DateTime).Value = this.ARRIVAL;
con.Open();
comTreeHouse.ExecuteNonQuery();
drTree = comTreeHouse.ExecuteReader();
if (drTree.Read())
{
this.TREEHOUSE = drTree.GetInt32(drTree.GetOrdinal("Rows"));
}
con.Close();
SqlCommand comPavillion = new SqlCommand("CountCottages", con);
comPavillion.CommandType = CommandType.StoredProcedure;
comPavillion.Parameters.Add("@CottageType", SqlDbType.NVarChar).Value = "Pavillion";
comPavillion.Parameters.Add("@ReservedDate", SqlDbType.DateTime).Value = this.ARRIVAL;
con.Open();
comPavillion.ExecuteNonQuery();
drPavillion = comPavillion.ExecuteReader();
if (drPavillion.Read())
{
this.PAVILLION = drPavillion.GetInt32(drPavillion.GetOrdinal("Rows"));
}
}
这是我存储的程序:
ALTER PROCEDURE dbo.CountCottages
(
@CottageType nvarchar(50),
@ReservedDate datetime
)
AS
SELECT count(dbo.Cottages.CottageName)
FROM dbo.Cottages INNER JOIN
dbo.ResortTransactions ON dbo.Cottages.CottageID = dbo.ResortTransactions.CottageID
where dbo.Cottages.CottageType=@CottageType and dbo.ResortTransactions.Status != 'Cancelled' and dbo.ResortTransactions.ReservedDate != @ReservedDate
RETURN
我的代码出了什么问题?我希望有人可以帮助我:)。
提前致谢!
答案 0 :(得分:3)
由于没有太多关于如何使用数据的信息,所以这是一个猜测。我假设你想要一个小屋,其中有一个交易,其中1)状态未被取消,2)日期等于预订日期。如果是这样,这是查询:
SELECT count(dbo.Cottages.CottageName)
FROM dbo.Cottages
WERE CottageType=@CottageType
AND CottageID NOT IN
(SELECT CottageID FROM dbo.ResortTransactions
WHERE Status != 'Cancelled'
AND ReservedDate = @ReservedDate)
此外,您正在执行sproc两次 - 一次使用ExecuteNonQuery
,一次使用ExecuteReader
您应该返回一个值并使用ExecuteNonQuery
,创建一个参数存储返回值,或使用ExecuteScalar
快速从数据集中提取第一个结果。
我建议阅读更多有关基本SQL以及如何使用.NET执行查询的内容。
答案 1 :(得分:1)
您没有返回COUNT
。
声明一个变量,用结果初始化它并从过程中返回它:
ALTER PROCEDURE dbo.CountCottages
(
@CottageType nvarchar(50),
@ReservedDate datetime
)
AS
BEGIN
DECLARE @NumCottages int
SELECT @NumCottages = count(dbo.Cottages.CottageName)
FROM dbo.Cottages INNER JOIN
dbo.ResortTransactions ON dbo.Cottages.CottageID = dbo.ResortTransactions.CottageID
where dbo.Cottages.CottageType=@CottageType and dbo.ResortTransactions.Status != 'Cancelled' and dbo.ResortTransactions.ReservedDate != @ReservedDate
RETURN @NumCottages
END
然后使用SqlCommand.ExecuteScalar
代替ExecuteNonQuery
来获取值。
答案 2 :(得分:1)
Cmd.ExeceuteNonQuery()
通常用于执行过程而不期望返回结果。
但是在这里你正在寻找一个标量值。所以将它改为cmd.ExecuteScalar()
。同时从程序中返回计数。
答案 3 :(得分:0)
我会做一些假设 - 在玩这个时只是一个小小的提示我会在SQL查询中创建一个“便笺簿”并使用表变量进行测试,如下所示:
DECLARE @Cottages AS TABLE
(
Cottage_PK INT IDENTITY(1, 1) ,
CottageName VARCHAR(100) ,
CottageType VARCHAR(100)
)
DECLARE @Reservations AS TABLE
(
Reservation_PK INT IDENTITY(1, 1) ,
Cottage_FK INT ,
CheckinDate DATETIME ,
DepatureDate DATETIME ,
IsCanceled BIT
)
DECLARE @DateToCheck AS DATETIME ,
@CottageType AS VARCHAR(100)
SET @DateToCheck = '2012-09-15'
SET @CottageType = 'Some Type'
INSERT INTO @Cottages
( CottageName, CottageType )
VALUES ( 'CottageA', 'Some Type' )
INSERT INTO @Reservations
( Cottage_FK ,
CheckinDate ,
DepatureDate ,
[Status]
)
VALUES ( 1 , -- Cottage_FK - int
'2012-09-16' , -- CheckinDate - datetime
'2012-09-24' , -- DepatureDate - datetime
''
)
现在我假设如果你想检查一个日期可用的小屋,你需要根据签入日期和使用between
声明的签名日期进行检查。
SELECT COUNT(c.CottageName) AS 'Cottages availible'
FROM @Cottages c
INNER JOIN @Reservations r ON c.Cottage_PK = r.Cottage_FK
WHERE NOT @DateToCheck BETWEEN r.CheckinDate
AND r.DepatureDate
AND c.[status] != 'Cancelled'
AND c.CottageType = @CottageType
使用它进行测试 - 我在它返回的范围内传递了一个日期0并超出范围并返回1.一旦你高兴地将它移到你的存储过程。
CREATE PROCEDURE dbo.CountCottages
@DateToCheck DATETIME ,
@CottageType VARCHAR(100)
AS
SELECT COUNT(c.CottageName) AS 'Cottages availible'
FROM Cottages c
INNER JOIN ResortTransactions r ON c.Cottage_PK = r.Cottage_FK
WHERE NOT @DateToCheck BETWEEN r.CheckinDate
AND r.DepatureDate
AND c.[status] != 'Cancelled'
AND c.CottageType = @CottageType