tags:

views:

57

answers:

4

I'm writing stored procedures for the first time, and it's not working. The trouble is I can't see a reason for it not to work.

I'm running it through phpmyadmin 2.8.2.4. My MySQL version is 5.1. Here is the first part of the query:

create procedure under_user_type (in original_post int, out user_type int, out user_id longtext)
begin
    if exists (
        select *
            from wp_postmeta as pm
            where pm.post_id = original_post
            and pm.meta_key = '_tdomf_original_poster_id'
    ) then
        set user_type = 0;
        select pm.meta_value
            into user_id
            from wp_postmeta as pm
            where pm.post_id = original_post
            and pm.meta_key = '_tdomf_original_poster_id';

    elseif exists ( ...

I get the error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 9

Line 9 corresponds to that first select statement in the if exists ( ... ) then portion.

update:

I get the same error if I use:

create procedure under_user_type (in original_post int, out user_type int, out user_id longtext)
begin
    if 1=1 then begin
        set user_type = 0;
        select pm.meta_value
            into user_id
            from wp_postmeta as pm
            where pm.post_id = original_post
            and pm.meta_key = '_tdomf_original_poster_id';
        end;

Update Again:

Running the examples on this MySQL documentation page also gives me the "check your syntax near ''" error. I tried removing all tabs from the query but that did nothing.

Update a third time:

I can run this query:

create procedure blah()
begin
end;

but not this query:

create procedure blah2()
begin
   if 1=1 then
   begin
   end;
   end if;
end;

as I get the same error.

A: 

I don't think MySQL can handle "if exists". You could try

declare testMe integer default (select ID from ... where ...);

if testMe is not NULL then
...
Darcara
that's possible, but it seems my procedure fails even if I write `if 1=1 then`. Is it possible that PHPMyAdmin is doing something ridiculous with the query or executing it in a way that doesn't support creating procedures?
Carson Myers
you might also need the DELIMITER // begin ... end // instead of end;also for procedure blah2() you need an end before the end if
Darcara
I read in a PHP bug report (someone reported that delimiter didn't work from php) that changing the delimiter is only necessary from the command line, so it knows when to start executing a statement. The report said that MySQL didn't require you to change the delimiter when creating stored procedures from PHP
Carson Myers
@Darcara, yes, apologies for my numerous typos in that stupid example haha. Sadly the actual query I'm trying to run is correct in that manner, and even with the corrected blah2() example, it still won't execute.
Carson Myers
no problem. Interestingly your blah2 procedure works, if I add "//" at the very end and set the delimiter in phpMyAdmin to "//" in the text field directly below the query..
Darcara
I don't have that textbox, it might be my version of phpmyadmin, and unfortunately I cannot upgrade. Maybe phpmyadmin splits up each line by itself rather than using a multi-query function in php?
Carson Myers
Hmm, I'm almost entirely sure its the delimiter thats missing. The default delimiter is ';' to terminate the query, but since it is used within the definition mysql needs another delimiter to tell the query is finished. You could also do that through the mysql console if you have access to it, an example is on the [MySQL manual page](http://dev.mysql.com/doc/refman/5.1/en/create-procedure.html)
Darcara
I believe `delimiter` is specific to the CLI. MySql doesn't actually require a separate delimiter, but the CLI does to know when to split finish taking input and execute a query. I'm convinced that phpMyAdmin does something similar -- I got the query to work without changing the delimiter using php's mysqli::multi_query
Carson Myers
+1  A: 

The following works for me:

create procedure blah2()
begin
  declare s int;
  if exists(select 1) then
    set s=1;
  end if;
end;

I think your problem (in the very first example, before you try doing all of your experimentation) is that you didn't declare the variable user_type, so MySQL prints out a (very generic) error when it encounters a variable name that it's never seen before on line 9.

(As for all of your other examples, you should not do if ... then begin ... end; The proper syntax is if ... then ... elseif ... else ... end if)

Ken Bloom
How did you execute this query? Unfortunately I get the same error I have been getting. Maybe it's just phpMyAdmin? Also, if I have multiple statements in the if/elseif/else blocks, do I not need begin and end?
Carson Myers
ah, it turns out that the problem WAS PHPMyAdmin. I wrote a server-side PHP script that users mysqli and my procedure works fine. I then tested it in PHPMyAdmin and received the result I was looking for.
Carson Myers
@Carson, when you install a procedure in the CLI, you have to change the statement delimiter to something other than `;` so that the CLI doesn't split the statements itself when it encounters a semicolon. Hence, the `DELIMITER //` before the procedure definition in http://dev.mysql.com/doc/refman/5.0/en/if-statement.html. (But your error message wouldn't complain about line 9 if that were your problem.)
Ken Bloom
I got the query to work without changing the delimiter using php's mysqli::multi_query -- phpmyadmin must have been doing something different.
Carson Myers
A: 

The error is on line 9, when it encounters the first semi-colon.

You need to set the DELIMITER to something other than semi-colon if you're going to use semi-colons inside the body of your procedure.

Here's how to do that for your simplest example:

DELIMITER $$

create procedure blah2()
begin
   if 1=1 then
   begin
   end;
   end if;
end $$

DELIMITER ;
Ike Walker
line 9 is actually the beginning of the select statement, I omitted five lines before the code I posted. Also, I am not running this query through the command line, which is where changing the delimiter is necessary -- in fact I believe the delimiter command is specific to the command line interpreter. PHPMyAdmin must do something similar to the CLI while my version doesn't let me change the delimiter. I wound up writing a script to execute the code for me, and it worked without the delimiter.
Carson Myers
A: 

The problem is that PHPMyAdmin must be trying to split up the queries itself every time it sees a semicolon. This is what the MySQL CLI does, which is why it's necessary to change the delimiter when creating a stored procedure on the command line. However, my version of PHPMyAdmin (2.8.2.4) doesn't allow me to change the delimiter, so I just wound up with a bunch of unhelpful error messages.

I wound up writing a script on the remote server with a textarea and submit button that would pass the contents of the textarea to mysqli::multi_query. This function lets mysql handle the delimiters rather than trying to split it up itself, and so creating the procedure worked in this respect.

Another, easier route would be to use MySQL Workbench to connect to the database, possibly through ssh if the database only allows connections from localhost.

Carson Myers