2012-09-25 152 views
-1

我有一个计数数据有内部连接的问题。从数据库使用存储过程计数数据使用内部连接

我要统计有多少别墅可供选择,这里是我的表:

enter image description here

enter image description here

这里是我的代码在课堂上让山寨号码。

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 [email protected] and dbo.ResortTransactions.Status != 'Cancelled' and dbo.ResortTransactions.ReservedDate != @ReservedDate 

RETURN 

什么是错我的代码?我希望有人能帮助我:)

在此先感谢!

+2

你的问题是什么?你会得到例外,得到错误的号码或什么? –

+0

错误/错误结果是什么?你想得到什么结果? –

+0

我得到错误的号码,我总是得到0! :( –

回答

3

由于没有太多关于的信息如何使用您的数据,这里有一个猜测。我假设你想要有一个别墅的数量,其中1)状态未被取消,2)日期等于预定日期。如果是这样,这里的查询:

SELECT count(dbo.Cottages.CottageName) 
    FROM dbo.Cottages 
    WERE [email protected] 
     AND CottageID NOT IN 
     (SELECT CottageID FROM dbo.ResortTransactions 
     WHERE Status != 'Cancelled' 
     AND ReservedDate = @ReservedDate) 

而且正在执行存储过程的两倍 - 使用一次ExecuteNonQuery,一次使用ExecuteReader您应该返回值和使用ExecuteNonQuery,创建参数来存储返回值,或使用ExecuteScalar快速从数据集中提取第一个结果。

我建议您阅读更多关于基本SQL以及如何使用.NET执行查询。

+0

我会尽力的!谢谢!!!!! –

+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 [email protected] and dbo.ResortTransactions.Status != 'Cancelled' and dbo.ResortTransactions.ReservedDate != @ReservedDate 

RETURN @NumCottages 

END 

然后使用SqlCommand.ExecuteScalar代替ExecuteNonQuery来获取值。

1

Cmd.ExeceuteNonQuery()通常用于执行过程而不期望返回结果。 但是,在这里您正在寻找标量值。请将其更改为cmd.ExecuteScalar()。也要从程序中返回计数。

+0

我会尽力的! :) 谢谢! –

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 
相关问题