I have a SQL string and I need to get the table name from the main 'FROM' value. I need to find the last 'FROM' occurrence which may or may not have additional constraints following it. Here are a few ways the string could look:
$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account WHERE title = 'president'";
$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account LIMIT 1";
$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account OFFSET 3";
$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account ANYTHING_HERE_REALLY";
$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account";
Expected output for all is: Account
From scouring the forum any playing around, this is the direction I'm going, but I know it's not correct.
preg_match('/.*FROM\s([^]]+)\sWHERE/', $input, $output);
First of all, it is bad practice to use regular expressions for cascading content like (cascading) queries. But here we go...
Simply match the sequence of non-spaces after the FROM
.
Note: because of the greedyness of the Kleene star of the .*
, it will definitely look for the latest match. You're pattern actually aims to overspecify the problem by expecting a WHERE
clause.
preg_match('/.*FROM\s+(\S+)/', $input, $output);
Example (with the given examples and interactive php -a
):
$ php -a
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account WHERE title = 'president'";
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output);
array(2) {
[0]=>
string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account"
[1]=>
string(7) "Account"
}
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account LIMIT 1";
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output);
array(2) {
[0]=>
string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account"
[1]=>
string(7) "Account"
}
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account OFFSET 3";
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output);
array(2) {
[0]=>
string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account"
[1]=>
string(7) "Account"
}
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account ANYTHING_HERE_REALLY";
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output);
array(2) {
[0]=>
string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account"
[1]=>
string(7) "Account"
}
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account";
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output);
array(2) {
[0]=>
string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account"
[1]=>
string(7) "Account"
}
This should work for you:
preg_match_all('/FROM\s?(\S+)/', $input, $output);
$output:
Array
(
[0] => Array
(
[0] => FROM Contact
[1] => FROM Account
)
[1] => Array
(
[0] => Contact
[1] => Account
)
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.