-1

内部結合を使用してデータをカウントする際に問題が発生しました。

利用可能なコテージの数を数えたいのですが、ここに私のテーブルがあります。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

これが、コテージ番号を取得するクラスの私のコードです。

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

私のコードの何が問題になっていますか?誰かが私を助けてくれることを願っています:)

前もって感謝します!

4

4 に答える 4

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を2回実行しています。1回は使用しExecuteNonQuery、もう1回は使用しExecuteReaderます。値を返して使用ExecuteNonQuery、戻り値を格納するパラメータを作成するか、を使用ExecuteScalarしてデータセットから最初の結果をすばやく取得する必要があります。

基本的なSQLと、.NETを使用してクエリを実行する方法について詳しく読むことをお勧めします。

于 2012-09-25T13:23:51.827 に答える
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して値を取得します。

于 2012-09-25T13:23:36.573 に答える
1

Cmd.ExeceuteNonQuery()通常、結果が返されることを期待せずにプロシージャを実行するために使用されます。ただし、ここではスカラー値を探しています。そのため、これをに変更しcmd.ExecuteScalar()ます。また、プロシージャからカウントを返します。

于 2012-09-25T13:23:44.177 に答える
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
于 2012-09-25T13:36:48.593 に答える