演练:分析现有数据库的 Transact-SQL 代码

通过将数据库架构中的 Transact-SQL 代码导入数据库项目中,然后根据一组规则分析这些代码,可以提高这些代码的质量。 例如,如果您必须使用某个架构,但该架构并非由您开发,且从未验证过其质量,那么您可能希望找出该架构中的所有错误。 有关更多信息,请参见分析数据库代码以提高代码质量

在分析数据库代码之前,必须已将现有数据库的架构导入数据库项目中。 该项目所含代码的质量等级未知。 您希望采用所有适合静态代码分析的规则来分析 Transact-SQL 代码。 您以后可能决定为团队关闭某些规则,但对于此初始评估,您希望找出数据库代码中的所有潜在问题。 您审阅警告和导致这些警告的代码。 您将更正警告、禁止显示更多警告,然后重新分析数据库项目。

系统必备

在完成本演练之前,您必须完成演练:将现有数据库架构置于版本控制之下。 在该演练中,您会创建一个解决方案,其中包含名为 MyAdvWorks 的数据库项目。

配置用于分析数据库项目的规则

  1. 在 Visual Studio 中,打开 MyAdvWorks 解决方案。

  2. 在**“架构视图”**中,展开该数据库项目的节点(如果尚未展开)。

  3. 在**“数据”菜单上,指向“静态代码分析”,然后单击“配置”**。

    将出现数据库项目的代码分析属性。

  4. 在**“规则”**列表中,展开“设计”、“命名”和“性能”节点,以显示所有可用于分析 Transact-SQL 代码的规则。

  5. 验证是否选中了所有规则的复选框。

    您可以选中或清除某个规则类别(如“设计”)的复选框,从而选中或清除该类别中所有规则的复选框。

    提示

    通过选中某个规则的“将警告视为错误”复选框,可以将该规则视为错误而不是警告。

  6. 在**“文件”菜单上,单击“全部保存”**。

    接下来,您将分析数据库项目中的 Transact-SQL 代码。 在本演练中,您将手动启动分析,但您可以将分析配置为在每次成功生成数据库项目后启动。 有关更多信息,请参见如何:对数据库代码启用和禁用静态分析

分析数据库项目

  • 在**“数据”菜单上,指向“静态代码分析”,然后单击“运行”**。

    将对数据库项目中的 Transact-SQL 代码进行分析,并在**“错误列表”中显示警告。 如果未显示“错误列表”,请打开“视图”菜单,然后单击“错误列表”**。

    接下来,您将查看并更正一个警告。

查看并更正警告

  1. 在**“错误列表”**中,找到下面的警告:

    SR0014 : Microsoft.Rules.Data: Data loss might occur when casting from ASCII String(1) to SmallInt.

    导致此警告的代码位于名为“ufnGetStock.function.sql”的文件中。 您可以在第 12 行第 30 列找到这段代码。

  2. 在**“错误列表”中,右击该警告,然后单击“显示错误帮助”**。

    将显示有关规则 SR0014 的帮助主题。 您可以了解是什么触发了该规则、如何解决该警告,以及在什么情况下您可能会希望忽略该警告。 您还可以看到会导致此警告的一段 Transact-SQL 代码示例,以及可解决该警告的该代码的更新。

  3. 在**“错误列表”**中,双击该警告,或突出显示该警告并按 Enter。

    Transact-SQL 编辑器打开和显示出现警告的代码。 光标会显示在导致该警告的代码的开头。 在这种情况下,光标出现在 FROM 子句中,因为整数列“LocationID”正在与单个字符常数“6”进行比较。 将显示如下代码:

    CREATE FUNCTION [dbo].[ufnGetStock](@ProductID [int])
    RETURNS [int] 
    AS 
    -- Returns the stock level for the product. This function is used internally only
    BEGIN
        DECLARE @ret int;
    
        SELECT @ret = SUM(p.[Quantity]) 
        FROM [Production].[ProductInventory] p 
        WHERE p.[ProductID] = @ProductID 
            AND p.[LocationID] = '6'; -- Only look at inventory in the misc storage
    
        IF (@ret IS NULL) 
            SET @ret = 0
    
        RETURN @ret
    END;
    
    GO
    EXECUTE sp_addextendedproperty @name = N'MS_Description', @value = N'Scalar function returning the quantity of inventory in LocationID 6 (Miscellaneous Storage)for a specified ProductID.', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'FUNCTION', @level1name = N'ufnGetStock';
    
    
    GO
    EXECUTE sp_addextendedproperty @name = N'MS_Description', @value = N'Input parameter for the scalar function ufnGetStock. Enter a valid ProductID from the Production.ProductInventory table.', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'FUNCTION', @level1name = N'ufnGetStock', @level2type = N'PARAMETER', @level2name = N'@ProductID';
    
  4. 更新 SELECT 语句的代码,使之与下面的示例相符:

        SELECT @ret = SUM(p.[Quantity]) 
        FROM [Production].[ProductInventory] p 
        WHERE p.[ProductID] = @ProductID 
            AND p.[LocationID] = 6; -- Only look at inventory in the misc storage
    
  5. 在**“文件”菜单上,单击“保存 ufnGetStock.function.sql”**。

    接下来,您将检查并禁止显示另一个警告。

查看并禁止显示代码分析警告

  1. 在**“错误列表”**中,找到下面的警告:

    SR0011 : Microsoft.Rules.Data: Object name(Database Version) contains special characters.

    导致此警告的代码位于名为“AWBuildVersion.table.sql”的文件中。 您可以在第 3 行第 5 列找到这段代码。

    此时,您必须决定是否从对象名称中去除特殊字符。 借助数据库重构,可以自动更新所有对此对象的引用,以使这些引用包含正确的名称。 但这样做会破坏所有依赖旧名称的应用程序。 如果没有足够的信息来确定最佳做法,可先禁止显示该警告,直至您调查清楚做出更改的后果。 您还可以在 Visual Studio Team Foundation Server 中创建工作项,以跟踪此任务,甚至将此任务分配给其他人。

  2. 在**“错误列表”**中,单击“说明”列的标题。

    **“错误列表”**会按警告的说明对警告进行排序,将所有 SR0011 警告聚集在一起。

  3. 滚动**“错误列表”**,直至 SR0011 警告出现,然后突出显示该警告。

    如果您要忽略多个警告,可以单击列表中要忽略的第一个警告,然后在按住 Shift 键的同时,单击列表中要忽略的最后一个警告,从而突出显示连续的警告列表。

    提示

    通过右击任一突出显示的行,指向“创建工作项”,然后单击工作项的类型,可以根据此列表创建工作项。 如果您禁止显示该警告,直至可以更改名称,则应在工作项中包含一个指令,说明要在更改名称之后恢复显示该警告。 在本演练中为简洁起见,您将跳过创建工作项环节。

  4. 右击任一突出显示的行,然后单击**“禁止显示静态代码分析消息”**。

    名为 StaticCodeAnalysis.SuppressMessages.xml 的文件会添加到数据库项目中。 MyAdvWorks.dbproj 文件会从版本控制中签出。 禁止显示的警告将从**“错误列表”**中消失,列表中的警告会减少。

    提示

    如果您禁止显示针对数据库项目中某个文件的某个警告,则会禁止显示针对该文件的所有该警告。

    该 XML 文件中包含禁止显示的警告的列表。 若要恢复显示所有禁止显示的警告,可以删除该文件。 有关更多信息,请参见如何:不再禁止显示数据库代码分析的警告

    在最后一个过程中,您将重新分析数据库项目。

重新分析数据库项目

  • 在**“数据”菜单上,指向“静态代码分析”,然后单击“运行”**。

    将再次对数据库项目中的 Transact-SQL 代码进行分析,**“错误列表”**中显示剩余警告。 已更正或禁止显示的警告不会显示。

后续步骤

在典型的环境中,您将对**“错误列表”**中显示的每个警告进行分析。 然后,修正可以立即解决的问题,禁止显示可以忽略的问题,并为以后必须解决的问题创建工作项。 对于某些问题,您可以使用数据库重构来解决警告。 有关数据库重构的更多信息,请参见重构数据库代码和数据

在解决或禁止显示每个警告之后,您应运行数据库单元测试和应用程序测试,验证所做更改没有引入问题。 有关数据库单元测试的更多信息,请参见使用单元测试验证数据库代码

请参见

概念

分析数据库代码以提高代码质量