Sql 选择不存在列的行为

Sql 选择不存在列的行为,sql,Sql,给定具有此结构的表: create table person ( id int identity primary key, name varchar(256), birthday datetime ) 对于此查询: select id,name,birthday,haircolor from person 在这种情况下,SQL抛出错误的原因是什么?我在考虑,如果查询只对不存在的列返回null,那么它会有多灵活。支持或反对这种SQL语言设计的具体原因是什么?返回null太普通了。我

给定具有此结构的表:

create table person (
  id int identity primary key,
  name varchar(256),
  birthday datetime
)
对于此查询:

select id,name,birthday,haircolor from person

在这种情况下,SQL抛出错误的原因是什么?我在考虑,如果查询只对不存在的列返回null,那么它会有多灵活。支持或反对这种SQL语言设计的具体原因是什么?

返回null太普通了。我更喜欢这种方式。在您的流中,您可能可以捕获错误并返回null(如果需要)。但是,提供有关查询失败原因的更多信息比接收空值要好(并且可能会让您在JOIN和WHERE子句上搔头,因为这样您会假设有一个
haircolour
列,该列可能具有以下含义,例如:

  • 您可能会认为可以插入到字段中,因为您假定该列存在
  • 返回的结果不是数据库架构的准确表示
  • 给出错误是为了让您能够清楚地理解和指示您可以和 不行。它也在那里,所以你可以尽快捕捉异常、虫子、蜘蛛,当然还有令人毛骨悚然的爬虫。:)

    我们不想迎合懒惰的开发者


    做正确的事,做人
    -Russel Peters.

    MySQL有一个可怕的错误

    select field1,field2,filed3
    from table 
    group by field1
    
    任何数据库引擎都会返回“error,wtf do do do with the field2 and field3 in the select line(如果它们不是聚合或group by语句中的字段2和字段3)”

    另一方面,MySQL将为字段2和3返回两个随机值,而不返回错误(我称之为“做错事而不返回错误”)。这是一个可怕的错误,发现At MySQL没有正确处理group by的脚本数量是荒谬的…在给出意外结果之前给出一个错误,这个巨大的错误就不会是这样的问题

    在您看来,您不是在请求更多这种愚蠢的行为被传播……只是在select子句中,而不是在GROUPBY子句中

    编辑:

    打字错误传播也是如此

    从…中选择年龄、性别、颜色


    我更希望返回一个错误,说“great typo Styly”,而不是一个满是空值的错误字段。

    这会因为许多原因而不一致。一个简单的例子是使用
    *
    选择列:当您这样做时

    select id, name, birthday, hair_color from person
    
    并返回一个所有四列都存在的表(
    hair\u color
    在所有行上设置为
    null
    ),您可以合理地预期下面的查询

    select * from person
    
    返回至少四列,并且
    hair\u color
    是返回的列之一。但是,如果SQL允许不存在的列返回
    null
    s,情况就不会如此

    当模式中的列被重命名时,这也会产生难以发现的错误,但某些查询或存储过程没有重新处理以匹配新名称


    不过,一般来说,SQL引擎开发人员在可用性和“硬”错误检查之间进行权衡。有时,他们会放松一两个约束,以适应一些最常见的“简单”错误(例如忘记在分组查询中使用聚合函数;这是一个错误,但MySql可以让您侥幸逃脱)。但是,当涉及到模式检查时,SQL引擎不允许任何自满,将所有缺少的模式元素视为错误。

    这将导致无提示错误问题。出现编译时错误和运行时异常的全部原因是为了尽快捕获bug

    如果列名输入错误,并且返回null而不是错误,则应用程序将继续工作,但会导致各种错误。您可能会有一列保存用户设置,表示他们不想接收电子邮件。但是,您的查询有输入错误,因此它总是返回null。渐渐地,一些人开始报告他们正在设置“不发送电子邮件”设置,但仍然收到电子邮件。你必须搜索所有代码来找出原因。首先查看编辑此设置的表单,然后查看调用数据库以保存设置的代码,然后验证数据是否存在以及设置是否持久化,然后查看发送电子邮件的系统,然后逐步升级到数据库层,该层检索设置并仔细检查SQL中的输入错误


    如果一开始就抛出了一个错误,那么这个过程会容易多少?没有用户感到沮丧。不要在支持请求上浪费时间。无需浪费时间进行故障排除。

    为什么?有了错误消息,您就知道问题出在哪里了。如果数据库引擎为您提供了一个名为haircolor的列,其中包含结果中的所有空记录,那么您将不知道该列是否确实存在于数据库中。也许头发颜色确实存在,但只是包含了所有的零点。而且,对于任何一个答案都是个人偏好的主观性,这个问题没有明确的答案。我不认为这个问题特别主观。一个不存在的列的值是未定义的,null是未定义的,所以对我来说,数据库这么说是有意义的,并且允许查询更好地处理不同的数据库版本。为什么会有向下投票?这个问题和这个有什么不同?他们都在问什么是本质上无声的错误。仅仅因为你可能不喜欢这个问题的前提并不意味着它是坏的。关于语言设计中存在编译/解析时错误的原因,这仍然是一个很好的问题。就像这个问题一样,另一个问题是关于为什么我们不允许静默返回错误和强制错误引发运行时异常:@AaronLS您引用的链接中的问题询问开发人员在将值返回给父级时可以采取的不同途径,从而能够做出决策