Esto ocurrió en la oficina hoy. No tengo planes de hacer tal cosa, pero en teoría ¿podrías escribir un compilador en SQL? A primera vista, me parece estar completa, aunque extremadamente engorrosa para muchas clases de problemas.
Si no está completo, ¿qué requeriría para ser así?
Nota: No deseo hacer nada como escribir un compilador en SQL, sé que sería una tontería, así que si podemos evitar esa discusión, lo agradecería.
Resulta que SQL puede ser Turing completo incluso sin una verdadera extensión de 'scripting' como PL / SQL o PSM (que están diseñados para ser verdaderos lenguajes de programación, por lo que es un poco engañoso).
En este conjunto de diapositivas, Andrew Gierth demuestra que con CTE y Windowing SQL se está completando Turing, mediante la construcción de un sistema de etiquetas cíclicas , que ha demostrado ser Turing completo. Sin embargo, la función CTE es la parte importante: le permite crear subexpresiones con nombre que pueden referirse a sí mismas y, por lo tanto, resolver problemas de forma recursiva.
Lo interesante a tener en cuenta es que CTE realmente no se agregó para convertir SQL en un lenguaje de programación, solo para convertir un lenguaje de consulta declarativa en un lenguaje de consulta declarativa más potente. Algo así como en C ++, cuyas plantillas resultaron ser completas de Turing a pesar de que no estaban destinadas a crear un lenguaje de meta programación.
> Resulta que SQL ¿No debería decir: Resulta que SQL: 1999? Solo digo esto porque los CTE se agregaron en la versión 99 y demasiadas personas asocian sql estándar con SQL 92.
Ernesto
1
@JensSchauder que se puede generalizar a "Oracle $ tecnología es $ some_good_feature, aunque de una manera bastante enferma"
Se dice que un lenguaje de programación dado es completo de Turing si se puede demostrar que es computacionalmente equivalente a una máquina de Turing.
El TSQL está Turing completo porque podemos hacer un intérprete BrainFuck en TSQL.
El código proporcionado funciona en la memoria y no modifica una base de datos.
-- Brain Fuck interpreter in SQLDECLARE@Code VARCHAR(MAX)=', [>,] < [.<]'DECLARE@Input VARCHAR(MAX)='!dlroW olleH';-- Creates a "BrainFuck" DataBase.-- CREATE DATABASE BrainFuck;-- Creates the Source code tableDECLARE@CodeTable TABLE([Id] INT IDENTITY(1,1)PRIMARYKEYNOTNULL,[Command] CHAR(1)NOTNULL);-- Populate the source code into CodeTableDECLARE@CodeLen INT = LEN(@Code);DECLARE@CodePos INT =0;DECLARE@CodeChar CHAR(1);WHILE@CodePos <@CodeLen
BEGINSET@CodePos =@CodePos +1;SET@CodeChar = SUBSTRING(@Code,@CodePos,1);IF@CodeChar IN('+','-','>','<',',','.','[',']')INSERTINTO@CodeTable ([Command])VALUES(@CodeChar)END-- Creates the Input tableDECLARE@InputTable TABLE([Id] INT IDENTITY(1,1)PRIMARYKEYNOTNULL,[Char] CHAR(1)NOTNULL);-- Populate the input text into InputTableDECLARE@InputLen INT = LEN(@Input);DECLARE@InputPos INT =0;WHILE@InputPos <@InputLen
BEGINSET@InputPos =@InputPos +1;INSERTINTO@InputTable ([Char])VALUES(SUBSTRING(@Input,@InputPos,1))END-- Creates the Output tableDECLARE@OutputTable TABLE([Id] INT IDENTITY(1,1)PRIMARYKEYNOTNULL,[Char] CHAR(1)NOTNULL);-- Creates the Buffer tableDECLARE@BufferTable TABLE([Id] INT IDENTITY(1,1)PRIMARYKEYNOTNULL,[Memory] INT DEFAULT0NOTNULL);INSERTINTO@BufferTable ([Memory])VALUES(0);-- Initialization of temporary variables DECLARE@CodeLength INT =(SELECT COUNT(*)FROM@CodeTable);DECLARE@CodeIndex INT =0;DECLARE@Pointer INT =1;DECLARE@InputIndex INT =0;DECLARE@Command CHAR(1);DECLARE@Depth INT;-- Main calculation cycleWHILE@CodeIndex <@CodeLength
BEGIN-- Read the next command.SET@CodeIndex =@CodeIndex +1;SET@Command =(SELECT[Command]FROM@CodeTable WHERE[Id]=@CodeIndex);-- Increment the pointer.IF@Command ='>'BEGINSET@Pointer =@Pointer +1;IF(SELECT[Id]FROM@BufferTable WHERE[Id]=@Pointer)ISNULLINSERTINTO@BufferTable ([Memory])VALUES(0);END-- Decrement the pointer.ELSEIF@Command ='<'SET@Pointer =@Pointer -1;-- Increment the byte at the pointer.ELSEIF@Command ='+'UPDATE@BufferTable SET[Memory]=[Memory]+1WHERE[Id]=@Pointer;-- Decrement the byte at the pointer.ELSEIF@Command ='-'UPDATE@BufferTable SET[Memory]=[Memory]-1WHERE[Id]=@Pointer;-- Output the byte at the pointer.ELSEIF@Command ='.'INSERTINTO@OutputTable ([Char])(SELECT CHAR([Memory])FROM@BufferTable WHERE[Id]=@Pointer);-- Input a byte and store it in the byte at the pointer.ELSEIF@Command =','BEGINSET@InputIndex =@InputIndex +1;UPDATE@BufferTable SET[Memory]=COALESCE((SELECT ASCII([Char])FROM@InputTable WHERE[Id]=@InputIndex),0)WHERE[Id]=@Pointer;END-- Jump forward past the matching ] if the byte at the pointer is zero.ELSEIF@Command ='['ANDCOALESCE((SELECT[Memory]FROM@BufferTable WHERE[Id]=@Pointer),0)=0BEGINSET@Depth =1;WHILE@Depth >0BEGINSET@CodeIndex =@CodeIndex +1;SET@Command =(SELECT[Command]FROM@CodeTable WHERE[Id]=@CodeIndex);IF@Command ='['SET@Depth =@Depth +1;ELSEIF@Command =']'SET@Depth =@Depth -1;ENDEND-- Jump backwards to the matching [ unless the byte at the pointer is zero.ELSEIF@Command =']'ANDCOALESCE((SELECT[Memory]FROM@BufferTable WHERE[Id]=@Pointer),0)!=0BEGINSET@Depth =1;WHILE@Depth >0BEGINSET@CodeIndex =@CodeIndex -1;SET@Command =(SELECT[Command]FROM@CodeTable WHERE[Id]=@CodeIndex);IF@Command =']'SET@Depth =@Depth +1;ELSEIF@Command ='['SET@Depth =@Depth -1;ENDENDEND;-- Collects and prints the outputDECLARE@Output VARCHAR(MAX);SELECT@Output =COALESCE(@Output,'')+[Char]FROM@OutputTable;PRINT@Output;
Go
SQL como tal (es decir, el estándar SQL92) no está completo. Sin embargo, muchos de los lenguajes derivados de SQL, como PL / SQL de Oracle y T-SQL de SQL Server, entre otros, están completos.
PL / SQL y T-SQL ciertamente califican como lenguajes de programación, ya sea que SQL92 califique está abierto a debate. Algunas personas afirman que cualquier código que le dice a una computadora qué hacer califica como lenguaje de programación; según esa definición, SQL92 es uno, pero también lo es, por ejemplo, HTML. La definición es bastante vaga, y no es algo inútil discutir.
Estrictamente hablando, SQL ahora es un lenguaje completo de turing porque el último estándar de SQL incluye los "Módulos almacenados persistentes" (PSM). En resumen, un PSM es la versión estándar del lenguaje PL / SQL en Oracle (y otras extensiones procesales similares del DBMS actual).
Con la inclusión de estos PSM, SQL se volvió completamente completo
Una instrucción de selección ANSI, como se definió originalmente en SQL-86, no está completa porque siempre termina (excepto para los CTE recursivos y solo si la implementación admite una recursión arbitrariamente profunda). Por lo tanto, no es posible simular ninguna otra máquina de turing. Los procedimientos almacenados se están completando, pero eso es trampa ;-)
El TSQL está Turing completo porque podemos hacer un intérprete BrainFuck en TSQL.
BrainFuck intérprete en SQL - GitHub
El código proporcionado funciona en la memoria y no modifica una base de datos.
fuente
https://web.archive.org/web/20110807062050/http://channel9.msdn.com/forums/TechOff/431432-SQL-Turing-Completeness-question
Es una discusión de este tema. Una cita:
fuente
Estrictamente hablando, SQL ahora es un lenguaje completo de turing porque el último estándar de SQL incluye los "Módulos almacenados persistentes" (PSM). En resumen, un PSM es la versión estándar del lenguaje PL / SQL en Oracle (y otras extensiones procesales similares del DBMS actual).
Con la inclusión de estos PSM, SQL se volvió completamente completo
fuente
Una instrucción de selección ANSI, como se definió originalmente en SQL-86, no está completa porque siempre termina (excepto para los CTE recursivos y solo si la implementación admite una recursión arbitrariamente profunda). Por lo tanto, no es posible simular ninguna otra máquina de turing. Los procedimientos almacenados se están completando, pero eso es trampa ;-)
fuente
El PLSQL de Oracle y el TSQL de Microsoft están completos. La declaración select de Oracle en sí misma también se está completando.
fuente