it-swarm.com.de

Ist SQL- oder sogar TSQL-Turing abgeschlossen?

Das ist heute im Büro aufgetaucht. Ich habe nicht vor, so etwas zu tun, aber theoretisch könnten Sie einen Compiler in SQL schreiben? Auf den ersten Blick scheint es mir vollständig zu sein, obwohl es für viele Problemklassen äußerst umständlich ist.

Wenn es nicht vollständig ist, was würde es erfordern, um so zu werden?

Hinweis: Ich habe keine Lust, irgendetwas wie einen Compiler in SQL zu schreiben. Ich weiß, es wäre eine dumme Sache. Wenn wir diese Diskussion vermeiden können, würde ich es begrüßen.

153
Matthew Vines

Es stellt sich heraus, dass SQL Turing Complete auch ohne eine echte Skript-Erweiterung wie PL/SQL oder PSM (die als echte Programmiersprachen konzipiert sind, das ist also ein bisschen Betrug) sein kann.

In dieser Reihe von Folien beweist Andrew Gierth, dass mit CTE und Windowing SQL Turing Complete ist, indem er ein zyklisches Tag erstellt System , das sich als vollständig erwiesen hat. Die CTE-Funktion ist jedoch der wichtige Teil. Sie ermöglicht es Ihnen, benannte Unterausdrücke zu erstellen, die auf sich selbst verweisen können, und dadurch Probleme rekursiv zu lösen.

Das Interessante ist, dass CTE nicht wirklich hinzugefügt wurde, um SQL in eine Programmiersprache zu verwandeln - nur um eine deklarative Abfragesprache in eine leistungsfähigere deklarative Abfragesprache zu verwandeln. So ähnlich wie in C++, dessen Vorlagen sich als vollständig herausstellten, obwohl sie nicht dazu gedacht waren, eine Meta-Programmiersprache zu erstellen.

Oh, das Mandelbrot-Set in SQL ist ebenfalls sehr beeindruckend :)

202
Jan de Vos

Eine gegebene Programmiersprache wird als Turing-vollständig bezeichnet, wenn gezeigt werden kann, dass sie einer Turing-Maschine rechnerisch äquivalent ist.

Die TSQL ist Turing Complete, weil wir in TSQL einen BrainFuck -Interpreter erstellen können.

BrainFuck Interpreter in SQL - GitHub

Der bereitgestellte Code arbeitet im Arbeitsspeicher und ändert keine Datenbank.

-- Brain Fuck interpreter in SQL

DECLARE @Code  VARCHAR(MAX) = ', [>,] < [.<]'
DECLARE @Input VARCHAR(MAX) = '!dlroW olleH';

-- Creates a "BrainFuck" DataBase.
-- CREATE DATABASE BrainFuck;

-- Creates the Source code table
DECLARE @CodeTable TABLE (
    [Id]      INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Command] CHAR(1) NOT NULL
);

-- Populate the source code into CodeTable
DECLARE @CodeLen INT = LEN(@Code);
DECLARE @CodePos INT = 0;
DECLARE @CodeChar CHAR(1);

WHILE @CodePos < @CodeLen
BEGIN
    SET @CodePos  = @CodePos + 1;
    SET @CodeChar = SUBSTRING(@Code, @CodePos, 1);
    IF @CodeChar IN ('+', '-', '>', '<', ',', '.', '[', ']')
        INSERT INTO @CodeTable ([Command]) VALUES (@CodeChar)
END

-- Creates the Input table
DECLARE @InputTable TABLE (
    [Id]   INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Char] CHAR(1) NOT NULL
);

-- Populate the input text into InputTable
DECLARE @InputLen INT = LEN(@Input);
DECLARE @InputPos INT = 0;

WHILE @InputPos < @InputLen
BEGIN
    SET @InputPos = @InputPos + 1;
    INSERT INTO @InputTable ([Char])
    VALUES (SUBSTRING(@Input, @InputPos, 1))
END

-- Creates the Output table
DECLARE @OutputTable TABLE (
    [Id]   INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Char] CHAR(1) NOT NULL
);

-- Creates the Buffer table
DECLARE @BufferTable TABLE (
    [Id]     INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Memory] INT DEFAULT 0  NOT NULL
);
INSERT INTO @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 cycle
WHILE @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 = '>'
    BEGIN
        SET @Pointer = @Pointer + 1;
        IF (SELECT [Id] FROM @BufferTable WHERE [Id] = @Pointer) IS NULL
            INSERT INTO @BufferTable ([Memory]) VALUES (0);
    END

    -- Decrement the pointer.
    ELSE IF @Command = '<'
        SET @Pointer = @Pointer - 1;

    -- Increment the byte at the pointer.
    ELSE IF @Command = '+'
        UPDATE @BufferTable SET [Memory] = [Memory] + 1 WHERE [Id] = @Pointer;

    -- Decrement the byte at the pointer.
    ELSE IF @Command = '-'
        UPDATE @BufferTable SET [Memory] = [Memory] - 1 WHERE [Id] = @Pointer;

    -- Output the byte at the pointer.
    ELSE IF @Command = '.'
        INSERT INTO @OutputTable ([Char]) (SELECT CHAR([Memory]) FROM @BufferTable WHERE [Id] = @Pointer);

    -- Input a byte and store it in the byte at the pointer.
    ELSE IF @Command = ','
    BEGIN
        SET @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.
    ELSE IF @Command = '[' AND COALESCE((SELECT [Memory] FROM @BufferTable WHERE [Id] = @Pointer), 0) = 0
    BEGIN
        SET @Depth = 1;
        WHILE @Depth > 0
        BEGIN
            SET @CodeIndex = @CodeIndex + 1;
            SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex);
            IF @Command = '[' SET @Depth = @Depth + 1;
            ELSE IF @Command = ']' SET @Depth = @Depth - 1;
        END
    END

    -- Jump backwards to the matching [ unless the byte at the pointer is zero.
    ELSE IF @Command = ']' AND COALESCE((SELECT [Memory] FROM @BufferTable WHERE [Id] = @Pointer), 0) != 0
    BEGIN
        SET @Depth = 1;
        WHILE @Depth > 0
        BEGIN
            SET @CodeIndex = @CodeIndex - 1;
            SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex);
            IF @Command = ']' SET @Depth = @Depth + 1;
            ELSE IF @Command = '[' SET @Depth = @Depth - 1;
        END
    END
END;

-- Collects and prints the output
DECLARE @Output VARCHAR(MAX);
SELECT @Output = COALESCE(@Output, '') + [Char]
FROM @OutputTable;

PRINT @Output;
Go
29
Miroslav Popov

http://channel9.msdn.com/forums/TechOff/431432-SQL-Turing-Completeness-question/

Ist eine Diskussion zu diesem Thema. Ein Zitat:

SQL als solches (d. H. Der SQL92-Standard) ist nicht vollständig. Viele von SQL abgeleitete Sprachen, wie z. B. PL/SQL von Oracle und T-SQL von SQL Server, sind jedoch vollständig.

PL/SQL und T-SQL sind zweifellos Programmiersprachen. Ob SQL92 selbst geeignet ist, ist umstritten. Einige Leute behaupten, dass jeder Code, der einem Computer sagt, was zu tun ist, als Programmiersprache qualifiziert ist. durch diese Definition ist SQL92 eins, aber so ist es z.B. HTML. Die Definition ist ziemlich vage und es ist imo eine sinnlose Sache, darüber zu streiten.

26
Aiden Bell

Genau genommen ist SQL jetzt eine äußerst vollständige Sprache, da der neueste SQL-Standard die "Persistent Stored Modules" (PSMs) enthält. Kurz gesagt, ein PSM ist die Standardversion der PL/SQL-Sprache in Oracle (und anderen ähnlichen prozeduralen Erweiterungen des aktuellen DBMS).

Mit der Einbeziehung dieser PSMs wurde SQL vollständig

13
Jordi Cabot

Eine ANSI-Select-Anweisung, wie sie ursprünglich in SQL-86 definiert wurde, ist nicht vollständig, da sie immer beendet wird (mit Ausnahme von rekursiven CTEs und nur, wenn die Implementierung eine beliebig tiefe Rekursion unterstützt). Es ist daher nicht möglich, eine andere Turingmaschine zu simulieren. Gespeicherte Prozeduren sind abgeschlossen, aber das ist Betrug ;-)

12
usr