如何将条件插入SQL SELECT?

时间:2013-03-01 19:06:57

标签: php mysql

我想通过AJAX(到PHP后端)向我的数据库发出查询。我有4个表:公司,用户,发票,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的一个子集(带有别名的直接表列,带表和别名的左连接和内连接以及表达式的简单表达式)。

1 个答案:

答案 0 :(得分: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能力。

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