1

我想通过 AJAX(到 PHP 后端)向我的数据库发出查询。我有 4 个表:Company、Users、Invoices、Invoice_Lines。重要关系如下:

Users.Company_ID -> Companies.ID
Invoices.Company_ID -> Companies.ID
Invoice_Lines.Invoice_ID -> Invoices.ID

我用 PHP 编写了一个简单的解析器,它将提交的 SQL 查询分解为其组件(列、表和条件)。

我希望用户能够直接编写查询,但在将它们提交到 SQL 服务器之前对其进行修改,以便所有信息都受到登录用户的公司 ID 的限制。例如:

SELECT Users.ID, Users.Name, Users.Email
FROM Users

我希望查询变为:

SELECT Users.ID, Users.Name, Users.Email
FROM Users
WHERE Users.Company_ID = X

在一个更复杂的例子中:

SELECT Invoice_Lines.Subtotal
FROM Invoice_Lines
WHERE Invoice_Lines.Invoice_ID = 4

变成

SELECT Invoice_Lines.Subtotal
FROM Invoice_Lines
INNER JOIN Invoices ON (Invoice_Lines.Invoice_ID = Invoice.ID)
INNER JOIN Company ON (Invoice.Company_ID = Company.ID)
WHERE Invoice_Lines.Invoice_ID = 4 AND Company.ID = X

很明显,我必须创建与已经编写的语句不冲突的表别名。我不确定如何分析查询以确定最有效的方法是限制输入。

我打算只支持 SQL 的一个子集(带有别名的直接表列、带有表和别名的左连接和内连接以及简单的 where 表达式)。

4

1 回答 1

0

同样,我建议查看 Zend Framework 如何使用Zend_Db_Select以 OP 方式描述 SQL 语句。

1) 定义您的基本 SQL 语句,其中包括您从中选择列的所有表。

让我们说:

SELECT * 
FROM table1
LEFT JOIN table2 on table2.table1Id = table1.id
LEFT JOIN table3 on table3.table2Id = table2.id
LEFT JOIN table4 on table4.table3Id = table3.id

2)您将允许用户选择列(最终我也想像约束) -使用当然可以换出对象的数组。

$fields = array(
    'table1' => array(array('col1'/*actual field name*/ => 'col1_Alias' /*assigned alais*/), array('col2'=>'col2_Alias')
    'table2' => array(array('col1'=>'col1_Alias'), array('col2'=>'col2_Alias')
    etc...
);

在控制器上定义它,将其用于您在用户构建查询时为用户提供的选项。然后在他们提交选择以构建 SQL 时使用它...

伪代码...

foreach ($selectColumns as $table => $col) {
     $cols[] = "{$table}.{$col['field']} AS {$col['alias']}";
}

在该循环中,您可以跟踪引用的每个表,并可能决定您将执行的 SQL 语句中是否需要它。需要描述 JOINS 的性质才能正确执行此操作 - 再次输入 Zend_Db_Select 之类的 OOP 功能。

我的回答中没有多少肉,但希望它有所帮助。

于 2013-03-01T19:34:19.213 回答