【问题标题】:Besides a declarative language, is SQL a functional language?除了声明性语言之外,SQL 是函数式语言吗?
【发布时间】:2009-07-20 12:52:05
【问题描述】:

为什么是或为什么不?

【问题讨论】:

    标签: sql functional-programming


    【解决方案1】:

    不,SQL 不是函数式语言。范式有些不同。请注意,除了函数式编程语言之外,还有其他类型的声明式编程语言——典型的例子是逻辑编程和 PROLOG。

    从技术上讲,关系代数(SQL 的理论基础)实际上并不完整。尽管现代 SQL 方言添加了足够的过程特性,因此可以实现存储过程并在此级别图灵完备,但单个 SQL 查询并不是图灵完备的计算。关系代数具有哥德尔完备性。哥德尔完备性意味着表达任何可以用一阶谓词演算定义的计算的能力——基本上就是你所知道的普通逻辑表达式。

    【讨论】:

      【解决方案2】:

      函数是 SQL 中的一等对象吗?几乎不。所以我会说不。

      【讨论】:

      • 根据定义 - 不,但在思维方式(和调试)上相似
      • 每个 SQL 查询都是一个函数。也许你只是不喜欢这种语法。
      • 是的,它们是...... SELECT 是一个函数。如果你读过关系代数,你就会知道 SELECTION 和 PROJECTION 是函数/动作。你只是没有看到它写成Select(columns/expressions);
      【解决方案3】:

      对于什么是函数式语言(或者就此而言,什么是过程式或面向对象的语言)没有一个真正的定义。

      但我真的想不出太多指向 SQL 功能的东西。 它没有函数,没有递归,没有闭包,没有嵌套函数,没有作为一等类型的函数。

      一个更常见的问题是 SQL 到底是不是一种编程语言。它不是图灵完备的。

      【讨论】:

      • +1 表示未完成 - 我只是想将其添加到我的答案中:-(
      • SQL92 标准不是图灵完备的。 Oracle 的 PL/SQL 和 SQL Server 的 T-SQL 等正在图灵完备。
      • 是的,但问题是关于 SQL 本身,而不是各个供应商的扩展。
      【解决方案4】:

      SQL 被设计为一种声明性语言,从某种意义上说,您告诉what 您想要获取,而SQL 引擎决定how

      但是,SQL 对集合进行操作,函数的结果可以是OracleSQL ServerPostgreSQL 中的第一类集合。

      可以说SQL 是函数式语言,只要一个函数将一个集合作为其输入并产生一个集合作为其输出。

      也就是说,你可以这样写:

      SELECT  *
      FROM    mytable t
      JOIN    myfunction(x) f
      ON      f.col1 = t.col2
      

      ,甚至这个:

      SELECT  *
      FROM    mytable t
      CROSS APPLY
              myfunction(t.col2) f
      

      (在SQL Server

      或者这个:

      SELECT  t.*, myfunction(t.col2)
      FROM    mytable t
      

      (在PostgreSQL

      不过,这不是 SQL 标准的一部分。

      就像C++ 编译器试图找到将两个 floats 相乘的最佳方法(就普通代数而言),SQL 优化器试图找到将两个集合相乘的最佳方法(就关系而言代数)。

      C++ 中,您只需编写a * b 并依靠编译器为此生成最佳程序集。

      SQL 中,您编写SELECT * FROM a NATURAL JOIN b 并依赖优化器。

      然而,由于所有SQL 声明的声明性(没有双关语),大多数真正的优化器只能进行非常基本的查询重写。

      比如说,我所知道的任何优化器都无法对这个查询使用同样有效的计划:

      SELECT  t1.id, t1.value, SUM(t2.value)
      FROM    mytable t1
      JOIN    mytable t2
      ON      t2.id <= t1.id
      GROUP BY
              t1.id, t1.value
      

      对于这个:

      SELECT  id, value, SUM(t1.value) OVER (ORDER BY id)
      FROM    mytable
      

      ,更不用说更复杂的查询了。

      这就是为什么您仍然需要制定查询,以便它们使用有效的计划(同时仍然产生相同的结果),从而使 SQL 少一点声明性语言。

      我最近在我的博客上发了帖子:

      【讨论】:

      • 要具有功能性,必须允许函数将函数作为输入。仅仅允许函数存在是不够的。
      • @jalf: 喜欢functionA(x) CROSS APPLY functionB(functionA.col1)?
      【解决方案5】:

      一般来说,如果没有语法扩展(例如 PL/SQL、T-SQL),就不能编写函数。

      但它肯定是非常面向表达式的,这是它与函数式语言的共同特点。

      【讨论】:

        【解决方案6】:

        声明性和功能性?那将是一个电子表格。

        【讨论】:

        • 废话。电子表格不允许您将函数作为第一类对象传递。问题是,SQL 是否允许传递函数。在一定程度上确实如此。但还不足以应用许多常用的函数式编程技术。
        • @nomen IIRC 我的回答是双关语。告诉我,在那之后的 12 年里,我们是否同意“SQL”的含义?如果是关系和关系运算符,那么不,“传递函数”不是“允许的”。但是谁知道 SQL 产品会让你用它的专有代码做些什么疯狂的事情呢?不是我。
        • 一个函数是一组有序的元组,它满足某些关于它的值。您绝对可以将它们作为选择语句传递。当然,这不是一个非常方便的传递函数的接口。这是我的观点——即使是 ANSI sql 也暴露了一些功能主义,但不足以应用通常的函数式编程技术。你甚至可以在 SQL-99 中进行递归。
        【解决方案7】:

        我认为 SQL 和函数式语言彼此非常不同。在函数式语言中,计算是通过评估函数来完成的。函数不会改变状态。他们所做的只是根据他们的论点计算一个值。换句话说,函数不会引起副作用。函数式语言是通用的。

        SQL 是一种设计用于处理关系数据库管理系统的语言。它可以被视为一种特定领域的语言。它旨在处理“数据集”。它可以通过使用诸如 UPDATE 之类的命令来改变全局状态(即数据库)。没有函数被评估为一个值的概念。据我了解,SQL 甚至都不是图灵完备的。

        【讨论】:

        • 函数式语言必须以某种方式产生副作用,不是吗?
        【解决方案8】:

        既然函数式语言的意义在于您使用函数进行编程,我会说不。 SQL 正在使用关系进行编程(如果您甚至可以将 SQL 称为编程语言 - 在它的基本形式中,SQL 不是图灵完备的)。

        【讨论】:

          【解决方案9】:

          从某种意义上说:是的,SQL 是功能性的。 看看

          • SELECTmap()
          • WHEREfilter()
          • ORDER BYsort()
          • DISTINCTset()

          等等

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-08-17
            • 2011-09-04
            • 1970-01-01
            • 2012-04-10
            • 2020-05-12
            • 2011-01-21
            • 2011-02-28
            相关资源
            最近更新 更多