2012-09-25 126 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 
相關問題