exec tSQLt.SetFakeViewOn 'dbo.viewWithIssues';
GO
CREATE PROCEDURE TestChanges.[Test Data]
AS
BEGIN
...
exec tSQLt.FakeTable 'dbo.viewWithIssues', @identity=1, @ComputedColumns=1, @Defaults=1;
INSERT INTO dbo.viewWithIssues (clock_id, IsTerminated)
VALUES ('1111', '0'), ('2222', '1'), ('3333', '1')
...
END
GO
exec tSQLt.SetFakeViewOff 'dbo.viewWithIssues';
GO
然后在调用过程后继续填充#Actual和#Expected。 它返回的错误是:更新或插入视图或函数'dbo.viewWithIssues'失败,因为它包含派生或常量字段。
有谁知道怎么解决这个问题?
答案 0 :(得分:12)
问题是SQL Server在编译时捕获了这个问题,因此永远不会执行FakeTable。这就是SetFakeViewOn应该捕获的,但它目前无法可靠地工作。现在没有真正干净的方法,然后将插入和更新放入动态SQL:
CREATE PROCEDURE TestChanges.[Test Data]
AS
BEGIN
...
exec tSQLt.FakeTable 'dbo.viewWithIssues', @identity=1, @ComputedColumns=1, @Defaults=1;
EXEC('INSERT INTO dbo.viewWithIssues (clock_id, IsTerminated)'+
'VALUES (''1111'', ''0''), (''2222'', ''1''), (''3333'', ''1'');');
...
END
答案 1 :(得分:0)
我建议您使用insert语句创建一个存储过程,并在exec tSQLt.FakeTable
之后调用它。.
CREATE PROCEDURE TestChanges.[Test Data]
AS
BEGIN
...
exec tSQLt.FakeTable 'dbo.viewWithIssues', @identity=1, @ComputedColumns=1, @Defaults=1;
execute TestChanges.[Insert into viewWithIssues]
...
END
答案 2 :(得分:0)
正如Sebastian所说,动态SQL是必经之路。如果有很多列(特别是需要单引号的文本/日期类型),我将使用以下模式:
-- #1
SELECT TOP(0) *
INTO #tempView
FROM dbo.viewWithIssues
-- #2
INSERT INTO #tempView (clock_id, IsTerminated)
VALUES ('1111', '0'), ('2222', '1'), ('3333', '1')
-- #3
EXEC ('INSERT INTO dbo.viewWithIssues SELECT * FROM #tempView')
答案 3 :(得分:0)
在一些朋友的帮助下,我得以解决此问题! 我将tSQLt.FakeTable命令移至Setup.sql,因为tSQLt在该模式中的其他测试之前先运行它。我们通过在同一SQL查询中运行FakeTable命令和INSERT INTO命令来发现此异常。像这样:
EXEC [dbServername].tSQLt.FakeTable @TableName='vw_viewname', @SchemaName='dbo';
INSERT INTO [dbServername].dbo.vw_myView
(Column1, Column2, Column3, Column4, Column5, Column6, Column7)
VALUES ( '100513','C','2018-12-13','2019-03-25','2014-10-27',' ',40.500,'3');
那会导致错误: [TestSchemaName]。[测试usp_MyStuff_Get得到我的东西]失败:(错误)由于视图或函数'dbServername.dbo.vw_myView'包含派生字段或常量字段而导致更新或插入失败。
这有效:
CREATE PROCEDURE [TestSchemaName].[Setup]
AS
BEGIN
IF @@TRANCOUNT > 0
BEGIN
EXEC [dbServername].tSQLt.FakeTable @TableName='vw_viewname', @SchemaName='dbo'
END
ELSE
BEGIN
RAISERROR('Procedure was run without tsqlt.Run. Aborting procedure', 16, 1)
END
END
CREATE PROCEDURE [TestSchemaName].[Test usp_MyStuff_Get Get my stuff]
AS
BEGIN
IF @@TRANCOUNT > 0
BEGIN
--EXEC [dbServername].tSQLt.FakeTable @TableName='vw_viewname', @SchemaName='dbo'
--I moved the line above to the Setup.sql
INSERT INTO [dbServername].dbo.vw_myView
(Column1, Column2, Column3, Column4, Column5, Column6, Column7)
VALUES ( '100513','C','2018-12-13','2019-03-25','2014-10-27',' ',40.500,'3')
END
ELSE
BEGIN
RAISERROR('Procedure was run without tsqlt.Run. Aborting procedure', 16, 1)
END
END
GO
发布项目,然后从SSMS运行:
EXEC tsqlt.run '[TestSchemaName].[Test usp_MyStuff_Get Get my stuff]'