How to use query string inside IN statement in MySQL stored procedure

987 views Asked by At

friends I have a stored procedure. which taking an input. But the input is a Query string. When I'm executing that string in IN statement I'm not getting anything.

My Stored Procedure is:

CREATE DEFINER=`root`@`localhost` PROCEDURE `SampleProcedure`(IN category VARCHAR(255) 
  IN location VARCHAR(255),
  IN classification VARCHAR(255))

BEGIN
    SELECT u1.firstname , u1.lastname, u1.avatar , s1.address ,c1.cityName 
    FROM user u1,serviceprovider s1, city c1 
    WHERE s1.userId=u1.id 
    AND c1.cityId=s1.city
    AND s1.serviceProviderId 
    IN
    (SELECT DISTINCT serviceprovider_cl AS serviceProviderId FROM  db.serviceprovider_classification t1
      INNER JOIN
      db.locationid t2 ON t1.serviceprovider_cl=t2.serviceprovider_locationId
        INNER JOIN 
            db.serviceprovider_category t3 ON t2.serviceprovider_location
                INNER JOIN
                    db.serviceprovider_category t3 ON t2.serviceprovider_locationId=t3.serviceprovider_category
      WHERE 

       t1.serviceproviderclassification_classification IN (classification)
        AND
      t2.location_serviceLocation IN (location)
       AND
      t3.category_serviceProviderCategory IN (category) 
    );
END

In category, classification and location. I'm getting another query in String. So to execute that string or How to convert it into query or how to use string as Query?
Thanks

2

There are 2 answers

2
Aleksandar Miladinovic On BEST ANSWER

for this you can use something called Prepared Statements, you can find more about that here...

So here is an SQL Fiddle where you can see how prepared statement works...

As you can see in this simple stored procedure it is not complicated that much. Basically there is three step to do this.

First create string which will be used in prepared statement. You do this to connect your query and query you will get as a string (IN category VARCHAR(255)) into one statement.

In my Fiddle:

SET @myString = 
       CONCAT('SELECT * FROM t2 WHERE t1_id IN (', category, ')');

That is the hardest part. Than you should perapare statement from that string

PREPARE statement FROM @myString;

End than execute the statement

EXECUTE statement;

When you call your procedure you pass your string which will be part of statement:

CALL SimpleProcedure('SELECT id FROM t1 WHERE val1 = "myVal2"');

And that's the logic you should apply on your problem.

That should look like this:

CREATE DEFINER=`root`@`localhost` PROCEDURE `SampleProcedure`(IN category VARCHAR(255))
BEGIN

    SET @myString = 
        CONCAT('SELECT u1.firstname , u1.lastname, u1.avatar , s1.address ,c1.cityName 
    FROM user u1,serviceprovider s1, city c1 
    WHERE s1.userId=u1.id 
    AND c1.cityId=s1.city
    AND s1.serviceProviderId 
    IN
    (', category, 
       ' INNER JOIN
       db.serviceprovider_category t3 ON t2.serviceprovider_locationId=t3.serviceprovider_category
       WHERE 
       t3.category_serviceProviderCategory IN (', category, '))');

    PREPARE statement FROM @myString;

    EXECUTE statement;
END

EDIT: note that between ' and INNER JOIN there is one blank space because CONCAT, without that, would connect last word from 'category' query and inner join and that will cause you problem and your query wont work!

GL!

P.S. Also i notice that you mix both syntax when JOIN table (old comma separated JOIN and the new way) which is not look nice, it would be good to correct that and use new INNER JOIN syntax like you do in your sub query...

New EDIT (based on question edit)

CREATE DEFINER=`root`@`localhost` PROCEDURE `SampleProcedure`(IN category VARCHAR(255) 
  IN location VARCHAR(255),
  IN classification VARCHAR(255))

BEGIN
    SET @myString =
    CONCAT('SELECT u1.firstname , u1.lastname, u1.avatar , s1.address ,c1.cityName 
    FROM user u1,serviceprovider s1, city c1 
    WHERE s1.userId=u1.id 
    AND c1.cityId=s1.city
    AND s1.serviceProviderId 
    IN
    (SELECT DISTINCT serviceprovider_cl AS serviceProviderId FROM  db.serviceprovider_classification t1
      INNER JOIN
      db.locationid t2 ON t1.serviceprovider_cl=t2.serviceprovider_locationId
      INNER JOIN 
        db.serviceprovider_category t3 ON t2.serviceprovider_location
            INNER JOIN
                db.serviceprovider_category t3 ON t2.serviceprovider_locationId=t3.serviceprovider_category
  WHERE 

   t1.serviceproviderclassification_classification IN (', classification, ')
    AND
  t2.location_serviceLocation IN (', location, ')
   AND
  t3.category_serviceProviderCategory IN (', category, '))');

    PREPARE statement FROM @myString;
    EXECUTE statement;
END
1
i486 On

Subquery in IN statement is equal to JOIN with subquery's table. Why you need "exotic" syntax instead of simple join.