【问题标题】:How to convert array values to MySQL query using PHP SQL Parser?如何使用 PHP SQL Parser 将数组值转换为 MySQL 查询?
【发布时间】:2018-03-21 06:10:13
【问题描述】:

我正在使用 PHP SQL PARSER

我的代码

<?php
    require_once dirname(__FILE__) . '/../src/PHPSQLParser.php';

    $sql = 'SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
    FROM Orders
    LEFT JOIN Customers ON Orders.CustomerID=Customers.CustomerID where 
    Customers.CustomerName = "Siddhu"'; 

    $sql = strtolower($sql);
    echo $sql . "\n";
    $parser = new PHPSQLParser($sql, true);
    echo "<pre>";
    print_r($parser->parsed);
?>

我得到如下数组的输出

Array (
    [SELECT] => Array
        (
            [0] => Array
                (
                    [expr_type] => colref
                    [alias] => 
                    [base_expr] => orders.orderid
                    [no_quotes] => orders.orderid
                    [sub_tree] => 
                    [delim] => ,
                    [position] => 7
                )

            [1] => Array
                (
                    [expr_type] => colref
                    [alias] => 
                    [base_expr] => customers.customername
                    [no_quotes] => customers.customername
                    [sub_tree] => 
                    [delim] => ,
                    [position] => 23
                )

            [2] => Array
                (
                    [expr_type] => colref
                    [alias] => 
                    [base_expr] => orders.orderdate
                    [no_quotes] => orders.orderdate
                    [sub_tree] => 
                    [delim] => 
                    [position] => 47
                )

        )

    [FROM] => Array
        (
            [0] => Array
                (
                    [expr_type] => table
                    [table] => orders
                    [no_quotes] => orders
                    [alias] => 
                    [join_type] => JOIN
                    [ref_type] => 
                    [ref_clause] => 
                    [base_expr] => orders
                    [sub_tree] => 
                    [position] => 70
                )

            [1] => Array
                (
                    [expr_type] => table
                    [table] => customers
                    [no_quotes] => customers
                    [alias] => 
                    [join_type] => LEFT
                    [ref_type] => ON
                    [ref_clause] => Array
                        (
                            [0] => Array
                                (
                                    [expr_type] => colref
                                    [base_expr] => orders.customerid
                                    [no_quotes] => orders.customerid
                                    [sub_tree] => 
                                    [position] => 101
                                )

                            [1] => Array
                                (
                                    [expr_type] => operator
                                    [base_expr] => =
                                    [sub_tree] => 
                                    [position] => 118
                                )

                            [2] => Array
                                (
                                    [expr_type] => colref
                                    [base_expr] => customers.customerid
                                    [no_quotes] => customers.customerid
                                    [sub_tree] => 
                                    [position] => 119
                                )

                        )

                    [base_expr] => customers on orders.customerid=customers.customerid
                    [sub_tree] => 
                    [position] => 88
                )

        )

    [WHERE] => Array
        (
            [0] => Array
                (
                    [expr_type] => colref
                    [base_expr] => customers.customername
                    [no_quotes] => customers.customername
                    [sub_tree] => 
                    [position] => 146
                )

            [1] => Array
                (
                    [expr_type] => operator
                    [base_expr] => =
                    [sub_tree] => 
                    [position] => 169
                )

            [2] => Array
                (
                    [expr_type] => const
                    [base_expr] => "siddhu"
                    [sub_tree] => 
                    [position] => 171
                )

        )

)

现在我想使用这个数组生成查询。我为什么要这样做,稍后我会在这个数组中添加额外的参数。就像我在 WHERE 子句或表中传递附加条件

例如: 上一个查询

 $sql = 'SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
    FROM Orders
    LEFT JOIN Customers ON Orders.CustomerID=Customers.CustomerID where 
    Customers.CustomerName = "Siddhu"';

现在我想在 where 子句中再传递两个条件,例如 WHERE 条件 Customers.CustomerID = "123" and status = "Active" and created_by = 1;

所以我的最终查询是这样的

  $sql = 'SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
    FROM Orders
    LEFT JOIN Customers ON Orders.CustomerID=Customers.CustomerID where 
    Customers.CustomerName = "Siddhu" AND Customers.CustomerID = "123" and status = "Active" and created_by = 1;

那么我该如何实现呢,或者PHPSQLPARSER中是否有任何函数使用这个数组来生成查询?感谢您的提前,如有任何语法错误,我们深表歉意

【问题讨论】:

  • 基于这个数组,你想生成什么样的查询,放置一个示例查询
  • 相同的查询。但我在 where 子句上添加了附加条件。假设,在我的查询中,我在这里写了' where Customers.CustomerName = "Siddhu"' 我可以添加一个额外的过滤器,例如'where Customers.CustomerName = "Siddhu" and id =1 and created_on = '2018-03-21''像这样。也许添加额外的连接。所以我创建了一个提到的数组的数组。最后,我想将整个转换为查询@ManiMuthuPandi
  • @Siddhu 您现在面临的问题是什么?既然你有数组,那么构建 SQL 语句有什么问题?你的代码在哪里挣扎?请编辑您的问题以包含尝试将数组转换为 SQL 查询的代码并解释究竟是什么不起作用。
  • 问题已更新@Progman
  • 传递给附加数组到where条件。然后连接字符串进行查询

标签: php mysql sql-parser


【解决方案1】:

要从数组构建查询,PHPSQLParser 有一个 creator 方法,

来自这里的文档:Parser manual

您可以通过两种方式从解析器输出创建语句

使用构造函数

为方便起见,构造函数只是在提供的解析器树输出上调用 create() 方法。

 $parser = new PHPSQLParser('select 1');

 $creator = new PHPSQLCreator($parser->parsed);

 echo $creator->created;

使用 create() 方法

 $parser = new PHPSQLParser('select 2');

 $creator = new PHPSQLCreator();

 echo $creator->create($parser->parsed); 

 /* this is okay, the SQL is saved in the _created_ property. */

 /* get the SQL statement for the last parsed statement */

 $save = $creator->created;

当然因为$parser-&gt;parsedarray,你可以传递你自己的数组

echo $creator->create($myArray); 

要将条件添加到数组中,可以将其添加到WHERE 条件数组中

每个条件都有 3 个数组定义 colref(列名)、operator(好吧..运算符)和const(值)

棘手的部分是WHERE 的子数组中的position,因为您需要指定要插入这三个中的每一个的确切位置,因此基于您提供的示例中的WHERE,可以看到运算符=的位置是169(从0开始)

检查此工具以查看character position in a string(从 1 开始)。

并基于此Complexe example

您最终的 WHERE 数组应该如下所示(不过我不确定您是否需要 [no_quotes] 键):

[WHERE] => Array
(
    [0] => Array
        (
            [expr_type] => colref
            [base_expr] => customers.customername
            [no_quotes] => customers.customername
            [sub_tree] => 
            [position] => 146
        )

    [1] => Array
        (
            [expr_type] => operator
            [base_expr] => =
            [sub_tree] => 
            [position] => 169
        )

    [2] => Array
        (
            [expr_type] => const
            [base_expr] => "siddhu"
            [sub_tree] => 
            [position] => 171
        )
    
    // adding other conditions 

    [3] => Array
        (
            [expr_type] => operator
            [base_expr] => and
            [sub_tree] => 
            [position] => 180
        )
        
    [4] => Array
        (
            [expr_type] => colref
            [base_expr] => customers.CustomerID 
            [no_quotes] => customers.CustomerID 
            [position] => 184
        )

    [5] => Array
        (
            [expr_type] => operator
            [base_expr] => =
            [sub_tree] => 
            [position] => 205
        )

    [6] => Array
        (
            [expr_type] => const
            [base_expr] => "123"
            [sub_tree] => 
            [position] => 207
        )
        
    [7] => Array
        (
            [expr_type] => operator
            [base_expr] => and
            [sub_tree] => 
            [position] => 213
        )
            
    [8] => Array
        (
            [expr_type] => colref
            [base_expr] => status 
            [no_quotes] => status
            [position] => 217
        )

    [9] => Array
        (
            [expr_type] => operator
            [base_expr] => =
            [sub_tree] => 
            [position] => 224
        )

    [10] => Array
        (
            [expr_type] => const
            [base_expr] => "Active"
            [sub_tree] => 
            [position] => 226
        )
        
    [11] => Array
        (
            [expr_type] => operator
            [base_expr] => and
            [sub_tree] => 
            [position] => 235
        )
            
    [12] => Array
        (
            [expr_type] => colref
            [base_expr] => created_by  
            [no_quotes] => created_by 
            [position] => 239
        )

    [13] => Array
        (
            [expr_type] => operator
            [base_expr] => =
            [sub_tree] => 
            [position] => 250
        )

    [14] => Array
        (
            [expr_type] => const
            [base_expr] => 1
            [sub_tree] => 
            [position] => 252
        )
)

PS :我使用了您提供的多个条件的查询,并取消了缩进和换行符来确定位置,如果您没有所需的字符串输出,请使用这些值作为这应该只是一个例子。

我希望这会有所帮助,或者至少能给你一个想法并祝你好运。

【讨论】:

    【解决方案2】:

    老实说,我承认我无法完全理解这个问题。但试图从我能够理解的内容中回答它。

    我相信您想使用第一个查询的输出并生成另一个带有附加 where 子句的查询。您可以通过在原始查询本身中使用带有 CONCAT 的简单附加选择子句来做到这一点。将硬编码的原始查询与所需的列连接起来,并生成动态 SQL 作为附加输出列。

    SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate,
           CONCAT("SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate  FROM Orders LEFT JOIN Customers ON Orders.CustomerID=Customers.CustomerID WHERE Customers.CustomerName = \"Siddhu\"", " AND Customers.CustomerID = \"", Customers.CustomerID, " and status = \"Active\" and created_by = 1;")
    FROM Orders
    LEFT JOIN Customers ON Orders.CustomerID=Customers.CustomerID
    WHERE Customers.CustomerName = "Siddhu"
    

    如果状态字段也来自其中一个表,那么您可以中断 CONCAT 函数并改用该列名。希望能帮助到你。

    【讨论】:

      猜你喜欢
      • 2015-04-21
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 2020-08-21
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 2015-09-18
      相关资源
      最近更新 更多