Results 1 to 10 of 10

Thread: MySql Stored Procedures Woes

  1. #1
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default MySql Stored Procedures Woes

    Hi,

    I've been having some trouble with some database access code on MySql5.
    A few weeks ago this code worked fine without a hitch, now I'm getting dopey results.

    I have a couple of stored procedures which work together as part of a transaction.
    CreateNewBatch and InsertNewImage.

    Here's the scenario:
    I call the CreateNewBatch stored proc.
    For example CreateNewBatch('New Job', @outval1)
    I get an int back as an out parameter.
    So, we'll call the new BatchID = 52 for this example.

    Then I feed 52 (foreign key to batch table) into the InsertNewImage stored proc.
    For example InsertNewImage(52, '000000ca', @outval1)
    I would expect to get back the ID of the new record in the Image table in which 000000ca is inserted.
    Instead I keep getting back 52.

    I know my stored procedure works fine because I have run it and tested the out param within a MySql front end called SqlYog.
    Here's what I run:
    Qt Code:
    1. call InsertNewImage(40, 'Filename', @imageId);
    2. select @imageId;
    To copy to clipboard, switch view to plain text mode 
    The result is always an incrementing number which does represent the new Image table records being inserted.

    I create the above "call <proc>" string which I exec on a QSqlQuery.
    Here's the code for both the CreateNewBatch and InsertNewImage functions:
    Qt Code:
    1. int ImageCacheDataConnector::CreateBatch(const QString& jobName)
    2. {
    3. bool closeOnExit = false;
    4. if(!_dbase.isOpen())
    5. {
    6. _dbase.open();
    7. closeOnExit = true;
    8. }
    9.  
    10. QString command = QString("call CreateNewBatch('%1', @outval1)").arg(jobName);
    11.  
    12. QSqlQuery query;
    13. query.exec(command);
    14. query.exec("select @outval1");
    15. query.next();
    16.  
    17. if(closeOnExit)
    18. _dbase.close();
    19.  
    20. return query.value(0).toInt(); // New Batch ID
    21. }
    22.  
    23. bool ImageCacheDataConnector::InsertImage(int batchID, const QString& filename)
    24. {
    25. bool ret = false;
    26.  
    27. bool closeOnExit = false;
    28. if(!_dbase.isOpen())
    29. {
    30. _dbase.open();
    31. closeOnExit = true;
    32. }
    33.  
    34. QString command = QString("call InsertNewImage(%1, '%2', @outval1)").arg(batchID).arg(filename);
    35.  
    36. QSqlQuery query;
    37. query.exec(command);
    38. query.exec("select @outval1");
    39. query.next();
    40. int i = query.value(0).toInt(); // New Image ID
    41.  
    42. if(i > 0)
    43. {
    44. ret = true;
    45. }
    46.  
    47. if(closeOnExit)
    48. _dbase.close();
    49.  
    50. return ret;
    51. }
    To copy to clipboard, switch view to plain text mode 

    As stated in the Qt docco MySql can't make use of the standard bind parameters for stored procedures, so you have to execute a call to the proc with a session parameter variable called @outval1 (or anything starting with @) then call another select statement to "get" the values.

    In the above code, if I use @outval1 in each member function then I get the BatchID back rather than the ImageID when running InsertNewImage.
    If I change the out parameter name in the InsertNewImage call to anything different to that used in InsertNewBatch (or vice versa) then the return value from InsertNewImage is always 0.

    As I said, I'm calling CreateBatch , then InsertImage within a transaction.
    I was under the impression that using @outval1 type parameters as above meant the variable was around for the life of the QSqlQuery instance but it seems it's being shared for the life of the transaction in my case (maybe).
    If so then why wouldn't it be overwritten anyway with the second use of it in InsertImage?
    Can anyone explain why using any other parameter name yields a return result of 0?

    Remember that if I run InsertNewImage stored procedure manually within SqlYog I get the correct output parameter result.

    Here's a listing of the stored procedures I'm calling:
    Qt Code:
    1. CREATE DEFINER=`root`@`localhost` PROCEDURE `CreateNewBatch`(
    2. p_jobName varchar(32),
    3. out p_identity int
    4. )
    5. BEGIN
    6. declare m_jobID int;
    7. set p_identity = -1 ;
    8. select ID into m_jobID
    9. from job
    10. where job.JobName = p_jobName;
    11. # Stick code in here to order by batch number
    12. # and get the next batch number (maybe a function)
    13. if m_jobID > -1
    14. then
    15. insert into batch
    16. (
    17. JobID,
    18. Status
    19. )
    20. values
    21. (
    22. m_jobID,
    23. 1
    24. );
    25.  
    26.  
    27. set p_identity = LAST_INSERT_ID();
    28. end if;
    29. END$$
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. CREATE DEFINER=`root`@`localhost` PROCEDURE `InsertNewImage`(
    2. p_batchID int,
    3. p_cacheFilename varchar(128),
    4.  
    5. out p_identity int
    6. )
    7. BEGIN
    8. DECLARE m_nextPosition int;
    9. SET m_nextPosition = NextImageNumber(p_batchID);
    10. insert into image
    11. (
    12. BatchID,
    13. Filename,
    14. Position,
    15. Format,
    16. HasAlternate
    17. )
    18. values
    19. (
    20. p_batchID,
    21. p_cacheFilename,
    22. m_nextPosition,
    23. 'tif',
    24. 0
    25. );
    26. set p_identity = LAST_INSERT_ID();
    27.  
    28. END$$
    To copy to clipboard, switch view to plain text mode 
    NextImageNumber is a helper function I defined in MySql.

    I'm using Qt 4.2.0 and the problem is also happening when I switch back to 4.1.4
    Thanks in advance for any assistance,

    Steve York

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MySql Stored Procedures Woes

    Quote Originally Posted by stevey View Post
    Then I feed 52 (foreign key to batch table) into the InsertNewImage stored proc.
    For example InsertNewImage(52, '000000ca', @outval1)
    I would expect to get back the ID of the new record in the Image table in which 000000ca is inserted.
    Instead I keep getting back 52.
    Does it work if you use a different variable (say @outval2) in second call?

  3. #3
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MySql Stored Procedures Woes

    If I use anything other than @outval1 then I get a return value of 0.
    That said, if I change the first one in CreatBatch() top @outval2 and leave the one in InsertImage as @outval1 I also get 0 back.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MySql Stored Procedures Woes

    Quote Originally Posted by stevey View Post
    if I change the first one in CreatBatch() top @outval2 and leave the one in InsertImage as @outval1 I also get 0 back.
    I hope you did remember to update the variable names in select statements too.

    Did you upgrade Qt or MySQL recently?

  5. #5
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MySql Stored Procedures Woes

    Yes, I did the replaement in both the call and select statement.
    Maybe I need to recompile the MySql plugin against my MySql build.

    I'll let you know how it goes.

  6. #6
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MySql Stored Procedures Woes

    Well, I'm afrid a recompile made no difference.
    If I packaged up a test console application along with a DDL and stored procedures would someone be able to try it out and see if it's "just me"?


    Thanks

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MySql Stored Procedures Woes

    Quote Originally Posted by stevey View Post
    If I packaged up a test console application along with a DDL and stored procedures would someone be able to try it out and see if it's "just me"?
    Sure .

  8. #8
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MySql Stored Procedures Woes

    Hi,

    I've attached some source code which will call 3 DAL functions that I use in my main application.

    The process is:
    1 - Create 'Job'
    2 - Add a 'Batch'
    3 - Insert a number in 'Image's (just filenames)

    Each DAL call returns the ID column of each newly inserted row.
    This time things are a little different to my first post in this thread.
    Now I get no result back at all and no data is being inserted.
    It's like the Stored Procedure call isn't even being made.
    I've tried running it without a transaction and get the same results.
    I thought that maybe it was a permissions thing as I hadn't added 'localhost' as an address from which the user could connect (within MySql Admin).
    Still no joy.

    I've tested the "call..." and related "select @id" commands within a query tab in SqlYog and it all works fine.
    I could create a job, batch and add images.
    So it definitely looks like this just can't reach my stored procedures.

    It has worked before so I'm at a loss.
    I've included a .sql script which can be loaded with MySql Admin to build the test schema on your MySql instance.

    Thanks for any assistance,

    Steve York
    Attached Files Attached Files
    Last edited by stevey; 18th October 2006 at 16:00.

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MySql Stored Procedures Woes

    I've added "if( ! ... ) qDebug() << query.lastError();" around all query.exec() and got this:
    QSqlError(1318, "QMYSQL: Unable to execute query", "Incorrect number of arguments for PROCEDURE imagingsystem.CreateNewBatch; expected 4, got 2")
    QSqlError(1048, "QMYSQL: Unable to execute query", "Column 'BatchID' cannot be null")
    ...
    QSqlError(1048, "QMYSQL: Unable to execute query", "Column 'BatchID' cannot be null")
    Batch 1 = -1
    Image ID's:
    0
    ...
    Then I've changed CreateNewBatch to CreateNewJob in CreateJob() and got this:
    Batch 1 = 1
    Image ID's:
    1
    ...
    1

    Batch 2 = 2
    Image ID's:
    1
    ...
    1

    Batch 3 = 3
    Image ID's:
    1
    ...
    1
    so it looks like it worked... once (but it's due to auto increment fields).

  10. The following user says thank you to jacek for this useful post:

    stevey (19th October 2006)

  11. #10
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: MySql Stored Procedures Woes

    Hi,

    Yeah I realised after I read your message that I made a typo.
    It should have been a call to SP CreateNewJob in the CreatJob function (slaps head).

    The whole problem in the end was that my InertNewImage SP was flawed.
    The issue was that I wasn't checking the lasterror().
    In my full time job I do mostly C# programming, and ADO with SqlServer returns exceptions when things go haywire which causes the program to crash if you don't catch the exception.
    QSqlQuery obviusly handles it all completely differently.
    I figured that because there was no crash, then it was all okay.

    Another thing I'm used to also is returning -1 int my p_identity out parameter.
    If you set a value here then QSqlQuery will succeed on the .exec(command).
    So the key here is to never assign a value to the out parameters, so if somethings goes wrong and you don't get to the SET p_identity = LAST_INSERT_ID(); at the end of the SP, then the out parameter will return NULL, in turn causing the .exec() to return false.

    I now have my image records appearing.
    Thanks Jacek for pointing out the test and qDebug message (why did I not think of it ? ).
    It gave me the message I needed to work out how to proceed.
    Above all I need to drop my .net habits.


    Steve York

Similar Threads

  1. Qt4: How to use Stored Procedures?
    By pinktroll in forum Qt Programming
    Replies: 6
    Last Post: 28th August 2006, 13:46
  2. Qt 4.1.4 & Mysql 5 on Linux x64
    By bothapn in forum Installation and Deployment
    Replies: 7
    Last Post: 4th August 2006, 13:23
  3. Qt 4.1 OS on Windows & mysql
    By neeko in forum Installation and Deployment
    Replies: 10
    Last Post: 31st January 2006, 20:22

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.