Sql server 为什么SQL构建不验证明显的错误,我们如何实现自动验证?

Sql server 为什么SQL构建不验证明显的错误,我们如何实现自动验证?,sql-server,msbuild,Sql Server,Msbuild,通过手动用户测试在QA中发现有一个代码错误,经调查,这是一个明显的错误 CREATE PROCEDURE ProcedureA @A INT AS SELECT 1 GO CREATE PROCEDURE ProcedureB AS EXEC ProcedureA @B = 0 此外,手动执行这些CREATE语句不会引发任何错误 另一个例子 CREATE VIEW VW_MyTestView AS SELECT Column1 = 0 GO CREATE PROCEDURE My

通过手动用户测试在QA中发现有一个代码错误,经调查,这是一个明显的错误

CREATE PROCEDURE ProcedureA
  @A INT
AS SELECT 1
GO
CREATE PROCEDURE ProcedureB
AS EXEC ProcedureA @B = 0
此外,手动执行这些
CREATE
语句不会引发任何错误


另一个例子

CREATE VIEW VW_MyTestView AS
    SELECT Column1 = 0
GO
CREATE PROCEDURE MyTestProcedure AS
    SELECT Column1
    FROM VW_MyTestView
GO
ALTER VIEW VW_MyTestView AS
    SELECT Column2 = 0
CREATE PROCEDURE MyProcedure
    @MyFlag BIT = 0
AS BEGIN
    IF @MyFlag = 1
    BEGIN
        DECLARE @MyImportantVariable DATE = GETDATE()
    END

    EXEC MyOtherProcedureThatNeedsAnImportantValue
        @MyImportantParameter = @MyImportantVariable
END
它在修改对象时不验证依赖项


另一个骇人听闻的例子是
INSERT
语句,在
FROM
子句中列数不等,如下所示:

INSERT INTO MyTable(TheOnlyColumn)
SELECT
    Column1 = ...
    ,Column2 = ...
    ,Column3 = ...
至少在更改/创建存储过程时会发现此问题


另一个例子

CREATE VIEW VW_MyTestView AS
    SELECT Column1 = 0
GO
CREATE PROCEDURE MyTestProcedure AS
    SELECT Column1
    FROM VW_MyTestView
GO
ALTER VIEW VW_MyTestView AS
    SELECT Column2 = 0
CREATE PROCEDURE MyProcedure
    @MyFlag BIT = 0
AS BEGIN
    IF @MyFlag = 1
    BEGIN
        DECLARE @MyImportantVariable DATE = GETDATE()
    END

    EXEC MyOtherProcedureThatNeedsAnImportantValue
        @MyImportantParameter = @MyImportantVariable
END
没有错误,在不遵循任何声明的情况下引用值
@MyImportantVariable
时,该值将为
NULL
。实际上,我更希望在这种情况下抛出一个错误,因为调试一个意外的
NULL
值更困难


另一个类似于#1的例子是,在过去一年中,我在数千个门控TFS构建中幸存下来,导致我脸上长了一个鸡蛋:

CREATE PROCEDURE MyProcedure
    @MyRequiredVariable INT--has no default
AS BEGIN
    ...
END
GO
EXEC MyProcedure--omits required parameter

为什么MSBuild进程没有捕获这样的东西,这显然是无效的,并且有任何方法可以添加对此类引用错误的验证吗?在发布更改时,我可以理解前两种情况是必要的,因为否则您将面临无法刷新相互引用的定义的第22个难题,但第三种情况是不可能被接受的,第四种情况甚至不会用C#这样的语言编译


这也破坏了我们的门控签入生成验证过程。

发生这种情况是因为SQL Server存储过程的属性

如果它不是存储过程、函数、表或视图等,那么它在编译时就会出错

但SQL Server存储过程仅在创建时检查语法准确性,存储过程的定义按原样存储

它仅在运行时,在对象的第一次执行时
检查过程引用的内容,如果缺少任何内容,该过程将抛出错误。

发生这种情况是因为SQL Server存储过程的属性

如果它不是存储过程、函数、表或视图等,那么它在编译时就会出错

但SQL Server存储过程仅在创建时检查语法准确性,存储过程的定义按原样存储

它仅在运行时,在对象的第一次执行时
检查过程引用的内容,如果缺少任何内容,过程将抛出错误。

除非编写软件的开发团队参与进来,否则此类问题不太可能得到具体答案。如果你觉得这是一个缺陷,你应该将其提交给适当的公司/团体考虑。我不敢相信有4个人投票结束了这个问题
主要是基于意见的
你在开玩笑吗??这是一个恰当而有效的问题,但如果你不知道答案,就不要投票来结束它。我怀疑这是因为我使用了“显而易见”之类的固执己见的词语,我仍然坚信这些词语是恰当的(也是一种专业的断言,而不仅仅是一种观点)。如果它们不明显,我恳请你评论一下原因,因为我不明白为什么现代语言会合理地缺乏这种验证(注意到构建是最早的步骤之一,在这里可以自动检测到脸上有蛋的问题,从而大大降低了在开发过程中后期处理确定错误的成本)。除非编写软件的开发团队参与进来,否则此类问题不太可能得到具体的答案。如果您觉得这是一个缺陷,您应该将其提交给适当的公司/团体考虑。真不敢相信有4个人投票结束了这个问题
主要是基于意见的
你在开玩笑吗it’这是一个恰当而有效的问题,但如果你不知道答案,就不要投票来结束它。我怀疑这是因为我使用了一些固执己见的词语,如“显而易见”,我仍然坚信这些词语是恰当的(而且是一种专业的断言,而不仅仅是一种观点)如果它们不明显,我恳请你评论一下原因,因为我不明白为什么现代语言会合理地缺乏这种验证(注意到构建是最早的步骤之一,在这一步中,可以自动检测表面上的鸡蛋问题,从而大大降低开发过程后期处理确定错误的成本)。我完全理解这对于临时存储过程(例如,在运行时发生变异)的重要性,但我不知道有任何实际使用案例,其中永久存储过程无法像编译语言那样验证其引用。如果无法禁用延迟名称解析属性(?),也许一种解决方法是在构建结束时启用“不执行”并调用每个存储过程?但这似乎真的很有黑客味。因此,没有办法在构建中的非临时对象上禁用延迟名称解析?我完全理解为什么这对临时存储过程很重要(例如,在运行时发生了变异),但我不知道有任何实际使用案例,其中永久存储过程无法像编译语言那样验证其引用。如果无法禁用延迟名称解析属性(?),也许一种解决方法是在构建结束时启用no-execute并调用每个存储过程?但这似乎真的很有黑客味。因此,没有办法在构建中的非临时对象上禁用延迟名称解析?