1

その時、私は別のものを持っています。これは、以前に使用していたものと同じ proc です。結果は私が必要としていたものではなかったので、製図板に戻りました。システムは同じです:

|| SQL Server 2005 || || エクセル 2007 || SQL 管理スタジオ 2008R2

2 つの日付の比較に問題があります。SSMS がスローしているエラーは意味がありません。コードは次のとおりです。

declare @calendar_start char(8)
declare @years int

set @calendar_start = '20130101'
set @years = 1

----------------------------------------------------------------------------
-- standard declaration stuff.  -
----------------------------------------------------------------------------

-- for ease of entry, I convert the start timeto a real time ---------------
----------------------------------------------------------------------------
declare @startdate datetime
set     @startdate = CONVERT (datetime, @calendar_start, 112)

-- to calculate the end of the forecast, I use the start date and add the --
-- provided number of year -------------------------------------------------
----------------------------------------------------------------------------
declare @enddate datetime
set     @enddate = dateadd(year,+@years,@startdate)
----------------------------------------------------------------------------

-- I need a variable to advance the plotting month. the plotting month is --
-- how I am going to spread out the project all year from a single date ----
----------------------------------------------------------------------------
declare @counter int
set     @counter = 0
----------------------------------------------------------------------------

----------------------------------------------------------------------------
-- this table will be used to have all the calendar dates by year-month ----
----------------------------------------------------------------------------
create table #calendar (calenderid char(6))

insert into #calendar
    select 
        distinct left(calendarid,6) [yearmonth]
    from 
        [cmdb_core].[dbo].[Calendar] 
    where 
        datevalue between @startdate and @enddate
----------------------------------------------------------------------------

----------------------------------------------------------------------------
-- rather than hitting the database any number of times, I load the whole --
-- of the computed estimates table into memory. it is faster that way.  ----
----------------------------------------------------------------------------
create table #baseline (
    [adjusted_ExpectedActionDt] datetime
    ,[key] text
    ,projectid text
    ,projectnm text
    ,ParentChaseProjectNo text
    ,VersionTag text
    ,itemid text
    ,Qty int
    ,ItemNotes text
    ,CashflowType text
    ,frequency text
    ,UnitPrice float
    ,[cost] float
)

insert into #baseline (
    [adjusted_ExpectedActionDt]
    ,[key]
    ,projectid
    ,projectnm
    ,ParentChaseProjectNo
    ,VersionTag
    ,itemid
    ,Qty
    ,ItemNotes
    ,CashflowType
    ,frequency
    ,UnitPrice
    ,[cost]
)
select  
    case
        when (ExpectedActionDt is not null)
            then ExpectedActionDt
        when (IntegratedReleasePlanDt is not null)
            then IntegratedReleasePlanDt
        else
            DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
    end [adjusted_ExpectedActionDt]
    ,cast(ModelEstimateId as nvarchar(max))+cast(BucketId as nvarchar(max))+cast(ItemNo as nvarchar(max)) [key]
    ,projectid
    ,projectnm
    ,ParentChaseProjectNo   
    ,VersionTag
    ,itemid
    ,Qty
    ,ItemNotes
    ,CashflowType
    ,frequency
    ,UnitPrice
    ,null [cost]
from 
    estimate.ComputedEstimates
where
        [status] <> 'Hold'
    and CostCategory <> 'Assembly'
    and includeinforecast = 'Y'
    and cashflowtype <> 'Notional'
    and Qty <> 0
    and case
            when (ExpectedActionDt is not null)
                then ExpectedActionDt
            when (IntegratedReleasePlanDt is not null)
                then IntegratedReleasePlanDt
            else
                DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
        end between @startdate and @enddate
--------------------------------------------------------------------------

--------------------------------------------------------------------------
-- we need a place to contain the results of the interation through the --
-- baseline temp table. the results table will be that. ------------------
--------------------------------------------------------------------------
create table #results (
    [adjusted_ExpectedActionDt] datetime
    ,[plot_date] datetime
    ,[key] text
    ,projectid text
    ,projectnm text
    ,ParentChaseProjectNo text
    ,VersionTag text
    ,itemid text
    ,Qty int
    ,ItemNotes text
    ,CashflowType text
    ,frequency text
    ,UnitPrice float
    ,[cost] float
)

-- this loop is how we will build the results. it is governed by the -----
-- date. as I iterate through the loop, I incriment the plot date so -----
-- that I can show a project and it's costs over the range of dates ------
-- rather than only the month it goes into production --------------------
--------------------------------------------------------------------------
WHILE (@startdate <= @enddate)
BEGIN
insert into #results (
    [adjusted_ExpectedActionDt]
    ,[plot_date]
    ,[key]
    ,projectid
    ,projectnm
    ,ParentChaseProjectNo
    ,VersionTag
    ,itemid
    ,Qty
    ,ItemNotes
    ,CashflowType
    ,frequency
    ,UnitPrice
    ,[cost]
)
select 
    [adjusted_ExpectedActionDt]
    ,dateadd(month,+@counter,[adjusted_ExpectedActionDt])
    ,[key]
    ,projectid
    ,projectnm
    ,ParentChaseProjectNo
    ,VersionTag
    ,itemid
    ,Qty
    ,ItemNotes
    ,CashflowType
    ,frequency
    ,UnitPrice
    ,case
        when frequency = 'OneTime' 
            then 
--=====================================================================--
--===================== this is where the problem is ==================--
--=====================================================================--           
                case
                    when dateadd(mm, datediff(mm,0, [adjusted_ExpectedActionDt]), 0) = 
                         dateadd(mm, datediff(mm,0, dateadd(month,+@counter,[adjusted_ExpectedActionDt])), 0)
                        then [Qty]
                    else
                        0
                end
--=====================================================================--
--=====================================================================--
        else
            cast(round((UnitPrice*Qty)/12,0) as int)
        end [cost]
 from #baseline

set @counter = @counter+1
set @startdate = dateadd(month,+1,@startdate)
END
--------------------------------------------------------------------------

--------------------------------------------------------------------------
-- now we have to return the results but it is not enough to just dump ---
-- the table, I have to add a date that covers all month regardless of ---
-- that month's presence in the results table. I use the calendar temp, --
-- which has those dates as a basis of the outer join --------------------
--------------------------------------------------------------------------

select  
    c.calenderid
    ,r.[adjusted_ExpectedActionDt]
    ,r.[plot_date]
    ,r.[key]
    ,r.projectid
    ,r.projectnm
    ,r.ParentChaseProjectNo
    ,r.VersionTag
    ,r.itemid
    ,r.Qty
    ,r.ItemNotes
    ,r.CashflowType
    ,r.frequency
    ,r.UnitPrice
    ,r.[cost] 
from 
    #calendar c
    left outer join
    #results r
    on c.calenderid = cast(year(r.[adjusted_ExpectedActionDt])as char(4))+RIGHT('0'+ CONVERT(VARCHAR,month(r.[adjusted_ExpectedActionDt])),2)
--------------------------------------------------------------------------
GO

問題は:

--=====================================================================--
--===================== this is where the problem is ==================--
--=====================================================================--           
                case
                    when dateadd(mm, datediff(mm,0, [adjusted_ExpectedActionDt]), 0) = 
                         dateadd(mm, datediff(mm,0, dateadd(month,+@counter,[adjusted_ExpectedActionDt])), 0)
                        then [Qty]
                    else
                        0
                end
--=====================================================================--
--=====================================================================--

このコードを実行しようとすると、次のエラーが発生します。

Msg 402, Level 16, State 1, Line 149
The data types text and varchar are incompatible in the equal to operator.

比較はテキストではなく日付の一致であるため、これは非常に厄介です。これは私が試したことです: 1. たくさんのインターネット検索 2. case ステートメントを if ステートメントに変更しましたが、正しい構文を得ることができませんでした。3.日付をdatepart関数に変更して、年のみを取得します。4. 比較を "1=1" に変更します。これは明らかに数値であり、常に true である必要があります。 5. 連結テキスト (yyyymm) への変換を試みました。タイトルではありませんが、このプロジェクトの終わりまでにそうなる予定です :) )

本当に奇妙なことは、この一般的なコードが機能することです

select 
    dateadd(mm, datediff(mm,0, getdate()), 0)
    ,dateadd(mm, datediff(mm,0, getdate()+60), 0)
    ,case
        when dateadd(mm, datediff(mm,0, getdate()), 0) = 
             dateadd(mm, datediff(mm,0, getdate()+60), 0)
            then 'matches'
        else
            'different'
    end

最後の情報は、[Qty] フィールドのみを残して問題のあるコードにコメントを付けると、問題なく動作するということです。

助けてオビ-誰でも、あなたは私の唯一の希望です。前もって感謝します。

4

1 に答える 1

1

問題はあなたの CASE ステートメントの一部ではないと思います。

when frequency = 'OneTime'

頻度列のデータ型はテキストであるためです。

あなたは試すことができます:

  when cast(frequency as varchar(20)) = 'OneTime'

か何か。

于 2013-03-18T19:05:08.737 に答える