0

I am new to MYSQL but have a basic understanding of SQL, and i am trying to say that if my parameter has not be set (ie null) then set it as JM.

What/where am i going wrong with the below script?

Thanks in advance

CREATE DEFINER=`james`@`%` PROCEDURE `Project_Status`(IN engineer VARCHAR (5))
BEGIN

SELECT 
    PP.pid_full,
    PP.description_small,
    PP.project_status,
    PP.est_comp_date as 'Est Comp Date',
    EP.engineer
FROM 
    project_pid pp
JOIN
    eng_project_hours EP on PP.pid_full = EP.pid_full

where engineer = ep.engineer;

IF engineer is null then update engineer = jm
set engineer = ep.engineer;
end if;

end
4
  • the update query is wrong; what are you trying to achieve, explain in words please Commented Mar 31, 2014 at 19:21
  • Basically, within the procedure if the variable has not been searched on, so the value is null, then set the value as JM (in my example) Commented Mar 31, 2014 at 19:23
  • Where is jm defined and do you expect this to SELECT or UPDATE the null value? Commented Mar 31, 2014 at 19:23
  • JM is a value within the EP table. I am expecting this to SET the value. I suppose you could say its a default value. Commented Mar 31, 2014 at 19:25

3 Answers 3

6

I'm not sure I understand what you are trying to do.

If you want to use a value of 'JM' instead of NULL when the input argument has a value of NULL, one way to get that kind of behavior is to declare a local variable in the procedure.

Check the value of the parameter, and set the value of the local variable accordingly; set the local variable to the literal value 'JM' when the input argument is null, or to the value of the input argument when it's not null. Then reference the local variable in the SQL statement.

Something like this:

DELIMITER $$

CREATE DEFINER=`james`@`%` PROCEDURE `Project_Status`(IN engineer VARCHAR(5))
BEGIN

   DECLARE ls_engineer VARCHAR(5);
   SET ls_engineer = IFNULL(engineer,'JM');

   SELECT pp.pid_full
        , pp.description_small
        , pp.project_status
        , pp.est_comp_date as 'Est Comp Date'
        , ep.engineer
     FROM project_pid pp
     JOIN eng_project_hours ep
        ON pp.pid_full = ep.pid_full
     WHERE ep.engineer = ls_engineer ;
END$$

Note that this:

   SET ls_engineer = IFNULL(engineer,'JM');

is easier-to-read shorthand equivalent to this:

   IF ( engineer IS NULL ) THEN
      SET ls_engineer = 'JM';
   ELSE
      SET ls_engineer = engineer;
   END IF;

FOLLOWUP

Q: Say for instance, where i have 'JM' i wished for the procedure to select all the records, is that something that can be done within this?

A: Yes. Let's say, for example, if the input parameter has the "special value" of 'JM', you don't want any restriction on the ep.engineer column at all, you could tweak the query by adding an OR condition to the WHERE clause...

WHERE ep.engineer = ls_engineer
   OR engineer = 'JM'

If the input parameter engineer has a value of 'JM', the predicate following the OR is is going to return TRUE for all rows, so it won't matter whether the part before the OR returns TRUE, FALSE or NULL, the overall result of the WHERE clause is going to be TRUE for all rows.

But I would suggest that NULL would be a more appropriate than 'JM' as a special "return all rows" value for the the input argument, with no need of a "default" value for the input parameter, i.e. no need to translate a NULL to 'JM'. But that really depends on your use case, but you might consider bypassing the JM default value altogether, and just do something like this in your query:

WHERE ep.engineer = engineer
   OR engineer IS NULL

Q: What is the reason/meaning for the ls_ prefix?

A:

The ls_ prefix is just a Hungarian-style notation I've used since Oracle PL/SQL days; I just found it a convenient way to help keep track of scope, and make for variable names that didn't conflict with other variable names, or with column names in SQL.

In a SQL statement, I can qualify column names to avoid ambiguity, but there's no way to qualify variables (apart from using bind parameters).

And I can define a local variable that has the exact same name as a global variable, and my local variable overrides (hides) the global variable, which is usually not what I want.

I'm not really a fan of Hungarian notation, especially not the Windows style lpszFoo and hwndBar, but the Hungarian notation was a convenience for me in Oracle PL/SQL.

I used first letter to identify scope of the variable, "l" for local, "g" for global, "a" for argument. The next letter was shorthand for the datatype of the variable, "s" for VARCHAR (string) type, "d" for DATE, "n" for NUMBER.

So, "as_" was an argument string, "ld_" was for a local date, etc.

Keeping track of the datatypes was important to avoid unintended implicit data conversions in SQL, and made an explicit conversion that was wrong look "wrong", e.g. there's no need for a TO_DATE() around a "date" or a TO_NUMBER around a number, but there is a need to cast a string to number, etc.

Sign up to request clarification or add additional context in comments.

5 Comments

This has worked exactly how i am looking for this to work. Thank you very much for this. Where you have put ls_engineer, can you explain this, what does "ls_" part mean? as this is not a table etc.
Say for instance, where i have 'JM' i wished for the procedure to select all the records, is that something that can be done within this?
Many Thanks for the help, it has seriously helped me with my work. I have more questions but I shall start a new question. Thanks again.
@user3482471: I apologize for posting a beast of an answer to your question, if it included more than you found useful.
No need, i found your answer helped me out couple of times when i was doing my query. So it was really useful. I am now looking to basically turn that same principle but using multiple variables.... turned out to be harder than i thought ha.
0

Just try this:

SELECT 
PP.pid_full,
PP.description_small,
PP.project_status,
PP.est_comp_date as 'Est Comp Date',
EP.engineer
FROM 
 project_pid pp
JOIN
 eng_project_hours EP on PP.pid_full = EP.pid_full
where ep.engineer = coalesce(engineer,"JM");

Comments

0

You can use COALESCE to return something except from null:

SELECT 
    PP.pid_full,
    PP.description_small,
    PP.project_status,
    PP.est_comp_date as 'Est Comp Date',
    COALESCE(EP.engineer,'jm')'
FROM 
    project_pid pp
JOIN
    eng_project_hours EP on PP.pid_full = EP.pid_full
WHERE engineer = ep.engineer;

Or with CASE and where JM is another column in EP:

SELECT 
    PP.pid_full,
    PP.description_small,
    PP.project_status,
    PP.est_comp_date as 'Est Comp Date',
    CASE WHEN EP.engineer IS NULL THEN EP.jm ELSE EP.engineer END AS engineer
FROM 
    project_pid pp
JOIN
    eng_project_hours EP on PP.pid_full = EP.pid_full
WHERE engineer = ep.engineer;

7 Comments

I have never used COALESCE before, but i have used the above script, and this is not seeming to bring back any results. I am expecting 2 results when i do not enter a value into the search field. Been racking my brain for 3 days now trying to get this.
What do you mean by "I am expecting 2 results when i do not enter a value into the search field"?
Thank you DHS, just tried that and and juggled things around to see if i could make it work, and it did seem to. I got an error saying that "unknown column 'JM' in 'field list'". So i guess its thinking where JM its trying to reference that against a table?
Sorry what i mean when i say that, is if have null as a value i should return results on my search.
JM needs to be defined - if it is another table then it needs a column... e.g. JM.mycolumn - and you need to join it also
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.