我正在尝试测试一个使用动态 sql 的存储过程,如下所示:
DECLARE @Sql NVARCHAR(MAX)
-- create @Sql
EXEC sp_executesql @Sql
,N'@NumberOfRollingMonths INT, @FromDate DATETIME, @ToDate DATETIME'
,@NumberOfRollingMonths = @NumberOfRollingMonths
,@FromDate = @FromDate
,@ToDate = @ToDate
无论我做什么,我都没有通过测试。我在用
EXEC tSQLt.FakeTable
伪造底层数据库的数据。tsqlt 不能与动态 sql 一起工作,这是一个众所周知的事实吗?
PS:
更多代码:
IF OBJECT_ID('TestDetails', 'U') IS NOT NULL
DROP TABLE TestDetails
CREATE TABLE TestDetails
(
Year INT,
Period INT,
HOURS INT
)
INSERT INTO TestDetails (Year, Period, HOURS)
SELECT 2004, 1, 10000 UNION ALL
SELECT 2004, 2, 100
IF OBJECT_ID('TestMonthsAndYears', 'U') IS NOT NULL
DROP TABLE TestMonthsAndYears
CREATE TABLE TestMonthsAndYears
(
Id INT not null identity(1,1) primary KEY,
TheMonth INT NOT NULL,
TheYear INT NOT NULL,
[Date] DATETIME NOT NULL
)
DECLARE @FromDate DATETIME
DECLARE @ToDate DATETIME
SET @FromDate = '1900-01-01 00:00:00.000'
SET @ToDate = '2200-01-01 00:00:00.000'
INSERT INTO TestMonthsAndYears
SELECT
TOP (DATEDIFF(MONTH, @FromDate, @ToDate) + 1)
[TheMonth] = MONTH(DATEADD(MONTH, number, @FromDate)),
[TheYear] = YEAR(DATEADD(MONTH, number, @FromDate)),
[Date] = DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, number, @FromDate)), 0)
FROM [master].dbo.spt_values
WHERE [type] = N'P'
IF EXISTS (SELECT * FROM sys . objects WHERE type = 'P' AND name = 'ToBeRemoved' )
DROP PROCEDURE ToBeRemoved
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description:
-- =============================================
CREATE PROCEDURE [dbo].[ToBeRemoved]
@FromDate DATETIME,
@ToDate DATETIME,
@NumberOfRollingMonths INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Sql NVARCHAR(MAX)
DECLARE @SumSql NVARCHAR(MAX)
SET @SumSql = N''
IF(@NumberOfRollingMonths > 0)
BEGIN
SET @NumberOfRollingMonths = @NumberOfRollingMonths * -1;
END
SET @SumSql = @SumSql + N' SUM(CAST(D.HOURS AS FLOAT)) '
SET @Sql = N'
;WITH SparseValues AS
(
SELECT
CAST(CAST(D.YEAR AS VARCHAR(4)) + RIGHT(''0'' + CAST(D.Period AS VARCHAR(2)),2) + ''01'' AS SMALLDATETIME) AS MonthYear,
' + @SumSql + ' AS Value
FROM TestDetails D
GROUP BY CAST(CAST(D.YEAR AS VARCHAR(4)) + RIGHT(''0'' + CAST(D.Period AS VARCHAR(2)),2) + ''01'' AS SMALLDATETIME)
)
,CompleteValues AS
(
SELECT
MY.[Date],
ISNULL(Value,0) AS Value
FROM TestMonthsAndYears MY
LEFT JOIN SparseValues SparseValues ON MY.[Date] = SparseValues.MonthYear
WHERE MY.Date BETWEEN @FromDate AND @ToDate
)
SELECT
S1.[Date],
AVG(S2.Value) AS MovingAverage
FROM CompleteValues AS S1, CompleteValues AS S2
WHERE S2.[Date] > DATEADD(m, @NumberOfRollingMonths,S1.[Date]) AND S2.[Date] <= S1.[Date]
GROUP BY S1.[Date] order by date'
EXEC sp_executesql @Sql
,N'@NumberOfRollingMonths INT, @FromDate DATETIME, @ToDate DATETIME'
,@NumberOfRollingMonths = @NumberOfRollingMonths
,@FromDate = @FromDate
,@ToDate = @ToDate
END
EXEC tSQLt.NewTestClass 'MyTestClass';
GO
CREATE PROCEDURE [MyTestClass].[test very good test]
AS
BEGIN
-- arrange
IF OBJECT_ID('Expected') IS NOT NULL DROP TABLE Expected;
IF OBJECT_ID('Actual') IS NOT NULL DROP TABLE Actual;
EXEC tSQLt.FakeTable 'dbo', 'TestDetails';
INSERT INTO dbo.TestDetails (Year, period, [HOURS])
SELECT 2004, 1, 30 UNION ALL
SELECT 2004, 2, 10
CREATE TABLE Expected(Date DATETIME, MovingAverage float)
CREATE TABLE Actual(Date DATETIME, MovingAverage float)
INSERT INTO Expected (Date, MovingAverage)
SELECT '2004-01-01 00:00:00.000', 30 UNION ALL
SELECT '2004-02-01 00:00:00.000', 10
-- act
DECLARE @FromDate DATETIME SET @FromDate = '2004-01-01 00:00:00.000'
DECLARE @ToDate DATETIME SET @ToDate = '2004-02-01 00:00:00.000'
DECLARE @NumberOfRollingMonths INT SET @NumberOfRollingMonths = -1
INSERT INTO Actual
EXEC ToBeRemoved @FromDate, @ToDate, @NumberOfRollingMonths
EXEC tSQLt.AssertEqualsTable 'Expected', 'Actual', 'Actual result table not equal to expected result table.';
END