0

I'm using PHP SQL PARSER

my Code

<?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);
?>

I'm getting output like below array

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
                )

        )

)

Now I want to generate the query using this array. Why am I doing this, later I will add additional parameters to this array. like I pass additional condition in WHERE clause or Table

FOR EXAMPLE: Previous query

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

Now I want to pass two more conditions in where clause like after WHERE condition Customers.CustomerID = "123" and status = "Active" and created_by = 1;

so here my final query is like

  $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;

So how can I achieve it, or Is there any function in PHPSQLPARSER using this array to have any function to generate the query? Thank you for Advance and Sorry for any grammar mistakes

Siddhu
  • 241
  • 2
  • 3
  • 16
  • Based on this array, what kind of query do you want to generate, Place a sample Query – ManiMuthuPandi Mar 21 '18 at 06:33
  • Same query. but I add additional conditions on where clauses. suppose, In my query, I wrote ' where Customers.CustomerName = "Siddhu"' here I can add an extra filter like 'where Customers.CustomerName = "Siddhu" and id =1 and created_on = '2018-03-21'' like this. maybe add extra joins. so I create an array of a mentioned array. finally, I want to convert entire into query @ManiMuthuPandi – Siddhu Mar 21 '18 at 06:37
  • @Siddhu What is the problem you are facing right now? Since you have the array what is the problem in building the SQL statement? Where are you struggle with your code? Please edit your question to include the code which tries to convert the array to an SQL query and explain what exactly isn't working. – Progman Mar 21 '18 at 18:52
  • Question updated @Progman – Siddhu Mar 26 '18 at 06:52
  • Pass to the additional array to where condition. Then concatenate the string to query – Siddhartha esunuri Mar 26 '18 at 07:10
  • The library contains something called PHPSQLCreator which convert this array back to an SQL statement – ahmad Mar 26 '18 at 16:59

2 Answers2

2

To build a query from the Array, PHPSQLParser has a creator method,

From the documentation here : Parser manual

There are two ways in which you can create statements from parser output

Use the constructor

The constructor simply calls the create() method on the provided parser tree output for convenience.

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

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

 echo $creator->created;

Use the create() method

 $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;

of course since $parser->parsed is an array, you can passe your own Array

echo $creator->create($myArray); 

To add a condition to the array, you can add it to the WHERE array of conditions

each condition has 3 arrays defining colref ( the column name ), operator ( well .. operator ) and const ( the value )

the tricky part is the position in the sub array of the WHERE as you need to specify where exactly you want to insert each one of those three, so based on the WHERE in the example you provided , you can see that the position of the operator = is 169 ( starting from 0 )

check this tool to see character position in a string ( this starts from 1 ).

And based on this Complexe example

Your final WHERE Array should look like this (i'm not sure if you need the [no_quotes] key though) :

[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 : i used the query with multiple conditions you provided and took off indentation and line breaks to figure out the positions, play around with those values if you don't have the desired string output as this is supposed to be just an example.

i hope this helps or at least gives you an idea and Good Luck.

Community
  • 1
  • 1
Taki
  • 17,320
  • 4
  • 26
  • 47
0

Honestly, I admit I was not able to fully understand the question. But trying to answer it from what I was able to comprehend.

I believe you want to use the output from first query and generate another query with additional where clause. You might just be able to do that by a simple additional select clause with CONCAT in original query itself. Concat your hardcoded original query with desired columns and generate your dynamic SQL as an additional output column.

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"

If the status field is also coming from one of the tables then you can break the CONCAT function and use that column name instead. Hope it helps.

Nik
  • 371
  • 4
  • 15