我正在尝试测试使用动态sql的sproc:
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
答案 0 :(得分:2)
正如其他人所评论的那样,Dynamic SQL可以与tSQLt一起使用。如果没有您遇到问题的代码/测试,很难确定问题所在的位置。
为了帮助您,并帮助您恢复对tSQLt的信心,以下是使用动态SQL的SP示例,以及调用它和假表的测试,以对该过程进行单元测试:
USE tSQLt_Example
GO
--Example table in which we will manipulate data
CREATE TABLE dbo.DynamicDemo (a INT)
GO
INSERT dbo.DynamicDemo (a) VALUES (5) -- This value will be removed by FakeTable
GO
--Example proc which uses Dynamic SQL
CREATE PROC dbo.DynamicAdd (@NoToAdd int) as
DECLARE @s NVARCHAR(MAX)
SET @s = 'update dbo.DynamicDemo set a=a+@NoToAdd'
EXEC sp_executesql @s,N'@NoToAdd int',@NoToAdd = @NoToAdd
GO
--create tSQLt class
exec tSQLt.NewTestClass @ClassName = N'DynamicTest' -- nvarchar(max)
GO
--Create test on proc which uses dynamic SQL
CREATE PROC DynamicTest.[test dynamic sql]
as
--Assemble
EXEC tSQLt.faketable 'dbo.DynamicDemo'
SELECT TOP 0 * into DynamicTest.Expected FROM dbo.DynamicDemo
INSERT dbo.DynamicDemo (a) VALUES (4) --Start position
INSERT DynamicTest.Expected (a) VALUES (7) -- Expected end position
--Act
EXEC dbo.DynamicAdd 3 --call proc under test
--Assert
EXEC tSQLt.AssertEqualsTable @Actual='dbo.DynamicDemo', @Expected = 'DynamicTest.Expected'
GO
--Run Tests
EXEC tSQLt.Run 'DynamicTest'
GO
--Clearup
DROP TABLE dbo.dynamicDemo
DROP PROC dbo.DynamicAdd
这个简单的例子应该有助于向您保证tSQLt本身能够正常使用动态SQL - 也许还有另一个依赖导致您出现问题?如果(正如其他人所说)你可以发布一个(可运行的)问题的例子,我们可以帮助你解决导致你这种痛苦的原因。