Regexp将sql LIMIT语法转换为SqlServer TOP语法

时间:2017-07-05 14:07:31

标签: c# sql-server regex postgresql regex-greedy

我有一些为PostgreSQL编写的查询字符串,我必须将它们转换为SqlServer。我正在使用C#6。

为了从LIMIT语法转换为TOP语法,我编写了以下简单的正则表达式:

SELECT ([\S\s]*)LIMIT (\d+) -> SELECT TOP $2 $1

完整的行代码是:

return Regex.Replace(query, @"SELECT ([\S\s]*)LIMIT (\d+)", "SELECT TOP $2 $1", RegexOptions.RightToLeft);

现在,eveything适用于简单查询,但它不适用于子查询:TOP字符串每次都放在超级父查询中。

尝试以下查询:

SELECT b3.aaa,
       b3.count
FROM
(
    SELECT CONCAT(b.foo / 100.0, '-', (b.foo + 10) / 100.0) AS aaa,
                      COUNT(b.foo) AS count
    FROM
    (
        SELECT b2.foo - (b2.foo % 10) AS foo
        FROM
        (
            SELECT CAST(b.foo * 100 AS INT) AS foo
            FROM eee b
                 INNER JOIN bar f ON b.bar_id = f.id
            WHERE b.foo < 1
                  AND f.nome = 'aaa'
        ) b2
    ) b
    GROUP BY b.foo
    ORDER BY b.foo
    LIMIT 10
)

它被转换为:

SELECT TOP 10 b3.aaa,
       b3.count
FROM
(
    SELECT CONCAT(b.foo / 100.0, '-', (b.foo + 10) / 100.0) AS aaa,
                      COUNT(b.foo) AS count
    FROM
    (
        SELECT b2.foo - (b2.foo % 10) AS foo
        FROM
        (
            SELECT CAST(b.foo * 100 AS INT) AS foo
            FROM eee b
                 INNER JOIN bar f ON b.bar_id = f.id
            WHERE b.foo < 1
                  AND f.nome = 'aaa'
        ) b2
    ) b
    GROUP BY b.foo
    ORDER BY b.foo
)

虽然我想

SELECT b3.aaa,
       b3.count
FROM
(
    SELECT TOP 10 CONCAT(b.foo / 100.0, '-', (b.foo + 10) / 100.0) AS aaa,
                      COUNT(b.foo) AS count
    FROM
    (
        SELECT b2.foo - (b2.foo % 10) AS foo
        FROM
        (
            SELECT CAST(b.foo * 100 AS INT) AS foo
            FROM eee b
                 INNER JOIN bar f ON b.bar_id = f.id
            WHERE b.foo < 1
                  AND f.nome = 'aaa'
        ) b2
    ) b
    GROUP BY b.foo
    ORDER BY b.foo
)

我应该如何编写我需要的正则表达式?

1 个答案:

答案 0 :(得分:1)

这对我处理引用的parens所做的一些改变是可行的:

var pattern = @"SELECT ((?:[^'()]|(?>'[^']+')|(?<open>\()|(?<-open>\)))+(?(open)(?!)))LIMIT (\d+)";

query = Regex.Replace(query, pattern, "SELECT TOP $2 $1");
相关问题