2

問題の解決策を 1 日中検索して見つけましたが、問題の解決策が見つかりませんでした。正規表現を使用して「展開」する必要があるクエリがあります。選択したフィールド、テーブル、および where 条件の後のフィールドを (チェック自体なしで) 取得したい。

SELECT `a`, `b`, `c` FROM `d` WHERE `e` > 1 OR `d` > 1

私の試みは次のようになります。

/SELECT (?<selectedFields>(,*?)\`(.*?)\`) FROM (?<tableName>\`(.*?)\`) WHERE (?<checkFields>\`(.*?)\`)/

私が抱えている問題は、where 条件の最初のフィールドの後に正規表現が停止することです。私が得た出力は次のようになります。

Array
(
[0] => Array
    (
        [0] => SELECT `a`, `b`, `c` FROM `d` WHERE `e`
    )

[selectedFields] => Array
    (
        [0] => `a`, `b`, `c`
    )

[1] => Array
    (
        [0] => `a`, `b`, `c`
    )

[2] => Array
    (
        [0] => 
    )

[3] => Array
    (
        [0] => a`, `b`, `c
    )

[tableName] => Array
    (
        [0] => `d`
    )

[4] => Array
    (
        [0] => `d`
    )

[5] => Array
    (
        [0] => d
    )

[checkFields] => Array
    (
        [0] => `e`
    )

[6] => Array
    (
        [0] => `e`
    )

[7] => Array
    (
        [0] => e
    )

)

選択したフィールドを取得したのと同じ種類の配列に「checkFields」が必要です。私は何を間違っていますか?2 つ目は、正規表現の selectFields が期待どおりに各フィールド名の配列ではなく、',' で区切られていることです...

4

2 に答える 2

4

正規表現を使用して SQL クエリを解析することは、正規表現を使用して html を解析することと非常に似ているため、正規表現を使用して SQL クエリを解析しないでください。そして、この答えは、なぜそれをすべきでないのかを明確に示しています。

いくつかのパーサーを使用することをお勧めします (例: this one )。

少しサンプル:

$sql = 'SELECT `a`, `b`, `c` FROM `d` WHERE `e` > 1 OR `d` > 1';
$sqlParser = new PHPSQLParser($sql);
echo '<pre>';
print_r($sqlParser->parsed);
于 2012-12-27T14:34:00.270 に答える
1

REGEX を使用すると、行き過ぎることはありません。考えられるすべての SQL クエリについて考えてみましょう。

SELECT * FROM tbl1 JOIN tbl2 
SELECT field as field2 FROM table1 as alias
etc

これにはパーサーが必要です。試してください: http://code.google.com/p/php-sql-parser/

また、SQL をまったく解析しないことをお勧めします。データベースに組み込まれている SQL パーサーは非常に複雑であり、その動作を模倣するのは簡単ではありません。

このような動作が必要な場合は、次のような逆のことを行う (SQL を構築する) シンプルなクラスを作成できます。

$s = new SQL();
$s->setFrom('table');
$s->addCondition('condition1','value1');
$s->select('*');  //> outputs SELECT * FROM table WHERE condition1 = 'value1'

したがって、すべてのパーツを取得するメソッドを使用できます。

$s->getConditions();
$s->getSelect();
于 2012-12-27T14:32:29.723 に答える