测试 SQL 查询的最佳方法[关闭]

2024-04-17

我遇到了一个问题,复杂的 SQL 查询总是出错。从本质上讲,这会导致向错误的客户发送邮件以及其他类似的“问题”。

大家对于创建这样的 SQL 查询有什么经验呢?我们每隔一周就会创建新的数据组。

以下是我的一些想法及其局限性:

  • 创建测试数据虽然这可以证明我们拥有所有正确的数据,但它并不能强制排除生产中的异常情况。这些数据在今天被认为是错误的,但在 10 年前可能是正确的;它没有记录在案,因此我们只有在提取数据后才知道它。

  • 创建维恩图和数据图这似乎是测试查询设计的可靠方法,但它并不能保证实现是正确的。它让开发人员提前计划并在编写时思考正在发生的事情。

感谢您对我的问题提供的任何意见。


您不会编写具有 200 行长函数的应用程序。您可以将这些长函数分解为较小的函数,每个函数都有一个明确定义的职责。

为什么要这样写 SQL?

分解您的查询,就像你分解你的功能一样。这使得它们更短、更简单、更容易理解,更容易测试,更容易重构。它允许您在它们之间添加“垫片”,并在它们周围添加“包装器”,就像在过程代码中一样。

你怎么做到这一点?通过将查询所做的每件重要事情都放入视图中。然后你compose从这些更简单的视图中创建更复杂的查询,就像从更原始的函数中组合出更复杂的函数一样。

最棒的是,因为most视图的组合,您将从 RDBMS 中获得完全相同的性能。 (对于有些人来说,你不会;那又怎样?过早的优化是万恶之源。首先正确编码,then如果需要的话进行优化。)

下面是使用多个视图来分解复杂查询的示例。 https://stackoverflow.com/questions/702500/sql-query-to-collapse-duplicate-values-by-date-range/712309#712309

在示例中,由于每个视图仅添加一个转换,因此每个视图都可以独立测试以发现错误,并且测试简单。

这是示例中的基表:

create table month_value( 
    eid int not null, month int, year int,  value int );

该表是有缺陷的,因为它使用两列(月份和年份)来表示一个数据,即绝对月份。这是我们对新计算列的规范:

我们将其作为线性变换来实现,这样它的排序与(年,月)相同,并且对于任何(年,月)元组都有一个且唯一的值,并且所有值都是连续的:

create view cm_absolute_month as 
select *, year * 12 + month as absolute_month from month_value;

现在我们必须测试的是我们规范中固有的,即对于任何元组(年,月),都有一个且只有一个(absolute_month),并且(absolute_month)是连续的。让我们写一些测试。

我们的测试将是 SQLselect查询,具有以下结构:测试名称和案例语句连接在一起。测试名称只是一个任意字符串。案例陈述只是case when测试语句then 'passed' else 'failed' end.

测试语句只是 SQL 选择(子查询),测试必须为真才能通过。

这是我们的第一个测试:

--a select statement that catenates the test name and the case statement
select concat( 
-- the test name
'For every (year, month) there is one and only one (absolute_month): ', 
-- the case statement
   case when 
-- one or more subqueries
-- in this case, an expected value and an actual value 
-- that must be equal for the test to pass
  ( select count(distinct year, month) from month_value) 
  --expected value,
  = ( select count(distinct absolute_month) from cm_absolute_month)  
  -- actual value
  -- the then and else branches of the case statement
  then 'passed' else 'failed' end
  -- close the concat function and terminate the query 
  ); 
  -- test result.

运行该查询会产生以下结果:For every (year, month) there is one and only one (absolute_month): passed

只要month_value中有足够的测试数据,这个测试就有效。

我们也可以添加一个测试以获得足够的测试数据:

select concat( 'Sufficient and sufficiently varied month_value test data: ',
   case when 
      ( select count(distinct year, month) from month_value) > 10
  and ( select count(distinct year) from month_value) > 3
  and ... more tests 
  then 'passed' else 'failed' end );

现在我们来测试一下它的连续性:

select concat( '(absolute_month)s are consecutive: ',
case when ( select count(*) from cm_absolute_month a join cm_absolute_month b 
on (     (a.month + 1 = b.month and a.year = b.year) 
      or (a.month = 12 and b.month = 1 and a.year + 1 = b.year) )  
where a.absolute_month + 1 <> b.absolute_month ) = 0 
then 'passed' else 'failed' end );

现在,让我们将测试(只是查询)放入一个文件中,然后针对数据库运行该脚本。事实上,如果我们将视图定义存储在一个脚本(或多个脚本,我建议每个相关视图一个文件)中以针对数据库运行,我们可以将每个视图的测试添加到same脚本,以便(重新)创建视图的行为也运行视图的测试。这样,当我们重新创建视图时,我们都会得到回归测试,并且当视图创建针对生产运行时,视图也将在生产中进行测试。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

测试 SQL 查询的最佳方法[关闭] 的相关文章

  • 为什么我们需要带有聚合函数的 GROUP BY?

    我看到一个例子 其中有一个员工列表 表 及其各自的月薪 我对工资进行了汇总 并在输出中看到了完全相同的表格 这很奇怪 这是必须做的 我们必须找出本月我们支付多少员工工资 为此 我们需要在数据库中对他们的工资金额进行求和 如下所示 SELEC
  • 如何从函数依赖中获取最小密钥?

    我需要一些帮助和指导 我有以下关系 R A B C D E F 以及函数依赖集 F AB gt C A gt D D gt AE E gt F R 的主键是什么 如果我应用推理规则 我会得到这些额外的函数依赖项 D gt A D gt E
  • 检查运行的代码是否为单元测试用例

    我想检查正在运行的代码是否是单元测试用例 或者不为结果执行不同的代码 例如 if unit test case is running do something else do other thing 对此有什么想法吗 这是一个糟糕的方法 您
  • 如何在没有 RawSQL 的情况下在 Django 中创建和访问正则表达式捕获组?

    如何在不使用 RawSQL 的情况下使用 Regex 捕获组注释 Django 查询集 以便稍后可以使用该值进行过滤和排序 例如 在 PostgreSQL 中我可以进行以下查询 CREATE TABLE foo id varchar 100
  • 如何对 SQL 查询进行单元测试?

    我有课DBHandler它接受一个查询 通过 SQL Server 运行它 检查错误并返回结果 我如何对这个类进行单元测试 Edit 我会尽量说得更准确 DBHandler负责将查询传递到服务器 为了测试它是否确实做到了这一点 抛出正确的异
  • 为带有yield的函数编写单元测试

    我正在尝试为使用生成器的函数编写单元测试 下面是我的代码 def extract data body for i in body a re sub lt lt gt str i b re sub view xc2 xa0book xc2 x
  • Sql Server 2005 将列名放在方括号中

    我最近将数据库从 Sql Server 2000 迁移到 Sql Server 2005 在表设计器中 它坚持将方括号放在名为 Content 的列周围 我在 Sql Server 的保留字列表中没有看到 Content 所以我不明白它为什
  • Oracle 10 中的本地临时表(适用于存储过程的范围)

    我是甲骨文新手 我需要在存储过程中处理大量数据 我正在考虑使用临时表 我正在使用连接池 并且该应用程序是多线程的 有没有一种方法可以为每次调用存储过程创建不同的表实例来创建临时表 以便来自多个存储过程调用的数据不会混淆 你说你是 Oracl
  • 如何在Windows窗体代码后面编写方法的单元测试

    我有想要测试的方法 但收到此错误 在创建窗口句柄之前无法在控件上调用 Invoke 或 BeginInvoke 现在我还有一个列表框 正在我正在测试的函数中填充 因此 当我将方法分离到另一个类时 这是一个问题 我理解这一点 因为表单需要首先
  • TDD中如何处理接口过度使用?

    我注意到 当我进行 TDD 时 它通常会导致大量的接口 对于具有依赖项的类 它们以通常的方式通过构造函数注入 public class SomeClass public SomeClass IDependencyA first IDepen
  • 如何在sql server中获取从当前日期时间到过去7天的过去7天的数据

    您好 我正在使用 pentaho 将表 A 数据从 sql server 加载到 mysql 加载数据时 我只需要从 sql server A 表获取最近 7 天的数据到 mysql 在sql server中createddate列数据类型
  • Oracle 求两个时间戳的平均值

    我不明白这有多难 但我似乎无法在任何地方找到解决方案 它是针对日期完成的 但我看不到让它适用于时间戳 我正在尝试做 select avg last timestmp ref timestmp as average from param 它一
  • 是否可以使用 jQuery 从 SQL Server 检索数据?

    是否可以使用 jQuery 从 SQL Server 检索数据并使用 HTML 控件显示数据 jQuery 被设计为在浏览器环境中运行 所以这是一个具有 DOM 的环境 具有 JavaScript 支持 显然 等等 要从 MS SQL Se
  • 表名或列名不能以数字开头?

    我尝试创建名为15909434 user语法如下 CREATE TABLE 15909434 user 这当然会产生错误 然后 在我尝试用谷歌进行一些研究后 我发现了一篇很好的文章here http www informit com art
  • 将一个巨大的字符串参数传递给存储过程

    我有一个存储过程 它有两个参数 ID 和日期 当我将大文本传递给 ID 参数时 仅考虑部分文本 就好像文本在某个地方被剪切一样 我想这是因为当我执行存储过程时如下 exec proc 1 2 3 4 20100101 一切正常 但是当我使用
  • 从 C# 程序集中执行 JavaScript

    我想从 C 程序集中执行 JavaScript 代码 并将 JavaScript 代码的结果返回到调用 C 代码 定义我不想做的事情更容易 我并不是试图从我的代码隐藏中调用网页上的 JavaScript 函数 我不想加载 WebBrowse
  • SailsJS:如何正确地对控制器进行单元测试?

    一直在使用 Sails js 但在为控制器进行 Jasmine 单元测试时遇到了困难 如果这是显而易见的事情 请原谅我的无知 因为我在过去的 3 4 个月里才深入研究 JavaScript 开发 在过去的框架 特别是 ASP Net MVC
  • 如何在多个Postgresql数据库之间共享表

    我的 Web 应用程序有多个部署 每个部署都是一个具有唯一 URL 的唯一站点 每个部署都有不同的数据 UI 等 但有非常相似的 Postgresql 数据库结构 带有 PostGIS 这些数据库都位于同一数据库服务器上 我希望来自 1 个
  • Oracle:在更新具有多列的表的一个字段时复制行

    有没有一种方法可以一般复制一行 特别是在不指定所有列的情况下 在我的情况下 我有一个大表 我想在其中复制除 ID 和另一列之外的所有列 事实上 数据是在年初复制的 该表有 50 多列 因此如果我不必指定所有列 则更改架构会更加灵活和稳健 这
  • 如何通过csv文件仅更新sql表的一列

    我有一个 csv 文件包含一些数据 在我的 Sql 数据库中 我有一个具有多个列名的表 现在我只想通过 csv 文件更新一列 谢谢 你可以这样尝试 Import the csv file to a temp table Update you

随机推荐

  • mojoPortal 还是 Umbraco?

    我已经寻找免费 开源 ASP NET CMS 门户系统有一段时间了 并将其分为两个不同的系统 乌姆布拉科 http umbraco org http umbraco org 魔力门户 http www mojoportal com http
  • 如何让 ASP.NET DataPager 控件在 UpdatePanel 中工作?

    我有一个顶部有参数的搜索页面 底部有一个带有结果的搜索按钮 整个内容都包含在母版页内的更新面板中 单击搜索按钮后 它会显示第一页 但是 如果您单击 DataPager 上的下一个按钮 它不会显示第二页 它显示第二页没有结果 任何帮助将不胜感
  • C++ 和 Java 中异常处理的区别?

    在Java中 如果特定的代码行导致程序崩溃 那么异常就会被捕获并且程序会继续执行 但是 在 C 中 如果我有一段代码导致程序崩溃 例如 try int x 6 int p NULL p reinterpret cast
  • 如何测试子组件是否已渲染?

    在酶中 您可以检查子组件是否存在 如下所示 expect wrapper find ChildComponent toHaveLength 1 React 测试库中的这个测试相当于什么 我找到的所有在线示例都只涵盖了寻找 dom 元素的非常
  • REST API 与 Web API

    我是构建 HTTP API 的初学者 我似乎对 REST API 和 Web API 之间的区别感到困惑 我在网上读到更多相关内容 困惑似乎越来越多 我猜菲尔丁有与此链接相同的问题http roy gbiv com untangled 20
  • 如何获取引用 postgresql 中的表的物化视图

    在 postgresql 中 借助 information schema views 表 可以通过简单的 sql 获取引用表的所有视图 但我需要一个等效的 sql 来获取引用该表的物化视图 欲查看以下作品 SELECT FROM infor
  • 为什么这个slideUp功能不流畅?

    我想实现 jQuery 的普通 JS 版本slideUp and slideDown 功能 我的想法是使用 CSStransition为了height属性以及使用增加 减少高度requestAnimationFrame 我用下面的代码尝试过
  • Selenium WebDriverJS,无法为 Chrome 构建 webdriver

    我在设置 Selenium WebDriverJS 时遇到一些问题 我的目标是使用 Javascript 节点 在 Chrome 浏览器上运行 selenium 测试 我正在按照以下说明进行操作https code google com p
  • 我需要关闭“PreparedStatement”吗? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我有一个网
  • 如何从 Azure 云功能引用“可移植”.NET 程序集?

    我已通过 Nuget 和 project json 成功引用了一个 可移植 程序集 我的所有代码都在 Azure 函数中编译 但是当它运行时我得到 无法加载文件或程序集 System Net Version 2 0 5 0 Culture
  • 获取 v2 Google 地图 API 密钥

    看来在我的网站开发和上线 现在 之间 Google 已经逐步淘汰了 Google Maps v2 API 我完全支持进步 但重写我所有的地图代码似乎对我来说有点难以处理 是否仍然可以在网络的某个隐蔽角落获取 Google 地图 v2 API
  • Delphi组件spTbxToolbar换肤

    如何在运行时通过代码 不适用于 groupskintype 更改 sptbxtoolbar 组件的皮肤类型 您只能一次更改所有 SpTBXLib 组件的外观 使用此代码 SkinManager SetSkin Office 2007 Blu
  • 使用drawImage()在画布上输出固定大小的图像?

    我该如何使用drawImage 在a上输出全尺寸图像300px X 380px画布无论源图像大小如何 例子 1 如果有一个图像75px X 95px我希望能够将其绘制以适合300px X 380px帆布 2 如果有一个图像1500px X
  • 使用 CSS 扩展边框

    我一直在测试使用一些嵌套 div 扩展 投影边框的想法 下面有一个工作示例 基本上 我想要实现的是垂直和水平边框延伸到盒子外面 里面有内容 有点像起草的样子 如果可能的话 我希望它能够完全响应 在我的代码中 我设置了带有负边距的高度 以便获
  • 为桌面构建 flutter 应用程序

    我看到一些人成功地为除通常的 Android IOS 之外的其他操作系统构建了 flutter 应用程序 我的问题很简单 如何 目前为 mac windows 构建 flutter 应用程序的流程是什么 没有必要这样生产准备就绪 一些实验性
  • Pandas groupby 根据另一列中的值(0 或 1)选择最后一行或倒数第二行

    我有一个与客户的数据框 每个客户都有一些观察结果和变量 其中一些不再是客户 我的问题如下 我想按客户分组 如果客户仍然是客户 则选择最后一行 如果客户不再是客户 则选择倒数第二行 对于客户的所有观察 我有一个名为 churned 的列 如果
  • 获取 Android 操作系统中已注册的 Pending Intent 列表

    我注册了计划在给定时间执行的警报 并且根据计划列表的大小 可以有很多警报 但我有两个问题仍然不清楚 1 如何在操作系统中查询我注册的待处理意图 我需要这个来测试 我想要的伪代码是这样的 List
  • 如何向 ionic 4 应用程序添加和使用 bootstrap?

    我正在构建一个 ionic 4 应用程序 我想使用 bootstrap 而不使用 CDN 方法 我已经使用 npm install bootstrap 安装了 bootstrap 在 Ionic 4 中 可以通过使用 angular jso
  • 如何更改 PostgreSQL 中的最大列宽?

    我有一个简单的 SQL 查询 它从一个表中选择几行 其中一列包含很长的字符串 我想设置最大列宽 以便更容易阅读 我无法通过 pset 访问环境变量 None
  • 测试 SQL 查询的最佳方法[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我遇到了一个问题 复杂的 SQL 查询总是出错 从本质上讲 这会导致向错误的客户发送邮件以及其他类似的 问题 大家对于创建这样的 SQL 查询有