4

In my database design, I tend to store some variable that is meant to be acting as a ROLE or TYPE as SMALLINT.

For example:

CREATE TABLE `house` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `type` smallint(11) NOT NULL,

And in PHP, I do:

define('HOUSE_SMALL_TYPE', '0');
define('HOUSE_MEDIUM_TYPE', '1');

So in PHP, in SELECT queries I do:

$this->db->query("SELECT * FROM house  
                  WHERE type = ?;", HOUSE_SMALL_TYPE);

My questions are:
  1. In the PHP part, is there is a better way to do this?
  2. In the MySQL itself, does MySQL also has global define functionality (like the define in PHP)?

I also want to do kind of

SELECT * FROM house  WHERE type = HOUSE_SMALL_TYPE;

in MySQL query.

My purpose is that when I do SELECT in MySQL, no way I'm going to keep mapping the value 0,1,2 with its real meaning. Just convenience for viewing the tables values, without changing the structure table and fields.

5
  • 2
    I think you looking for ENUM. Commented Mar 13, 2013 at 9:33
  • 1
    Define a criteria for "better way". What exactly you want to improve? Commented Mar 13, 2013 at 9:38
  • @Rikesh Means that I'll have to change my db type using ENUM right ? My tables some are created, but I'll take this into consideration for next creation table. Commented Mar 13, 2013 at 9:46
  • @HendryH. You can read the post I have linked too. Your question is vague so if you looking something like than use it. Commented Mar 13, 2013 at 9:49
  • @Your Common Sense Actually, I'm just curious how you guys do it in php. I consider any alternative, since I'm still in early development stage. Commented Mar 13, 2013 at 9:49

5 Answers 5

4

Since MySQL 5.5 it's not possible to set a global user-defined variable.

A work-around might be to create a stored procedure that would return what you need.

DROP PROCEDURE IF EXISTS HOUSE_SMALL_TYPE;
DELIMITER //
CREATE PROCEDURE HOUSE_SMALL_TYPE ()
BEGIN 
SELECT 0;
END//
DELIMITER ;

and then call it.

CALL HOUSE_SMALL_TYPE();

The DROP statement is required in order to be able to modify it.

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

Comments

2

IMHO, MySQL has a huge gap in this area, apparently in the latter versions. One alternative might have been to resort to setting OS environment variables, but how such values can be retrieved from within MySQL, I've been unable to see.

There's a whole page here: https://dev.mysql.com/doc/refman/5.0/en/setting-environment-variables.html teaching us how to "set" OS environment variables in the shell, but not a word on actually calling such variables in MySQL.

As another workaround, using a FUNCTION might be considered more lightweight than a STORED PROCEDURE, like so:

CREATE DEFINER=`root`@`localhost` FUNCTION `DEFAULT_COUNTRY_CODE`() RETURNS CHAR(4)
DETERMINISTIC
RETURN '+234';

Elsewhere in your query, you can then do:

SELECT CONCAT(DEFAULT_COUNTRY_CODE(), "-", telephone) FROM contacts WHERE CountryCode = "NGA"

1 Comment

It seems that there is no way MySQL can access to environment variables. As they state Environment variables can be set at the command prompt to affect the current invocation of your command processor... and that's it.
0

Your approach is fine, if you want to see the values in MySQL instead of 1, 2, 3 etc. then consider this:

define('HOUSE_SMALL_TYPE', 'HOUSE_SMALL_TYPE');
define('HOUSE_MEDIUM_TYPE', 'HOUSE_MEDIUM_TYPE');

Then in MySQL you can use:

SELECT * FROM house  WHERE type = 'HOUSE_SMALL_TYPE';

You just need to remember that you cannot just jam any value you like into house.type without having support for it in PHP.

Even better consider this:

class HouseType {
  const SMALL = 'SMALL';
  const MEDIUM = 'MEDIUM';
}

or

class House {
  const TYPE_SMALL = 'SMALL';
  const TYPE_MEDIUM = 'MEDIUM';
}

because then you can use HouseType::SMALL or House::TYPE_SMALL in your PHP code rather than using a global define. By doing this you may benefit from code completion in some IDE's.

Comments

0

Since MySQL 5.5 it's not possible to set a global user-defined variable, another workaround could be helping table like

create table glob_var(key varchar(10) unique not null, val varchar(10) not null);

Comments

-2

I suggest using MySQL variables:

SET HOUSE_SMALL_TYPE = 0;
SET HOUSE_MEDIUM_TYPE = 1;

Then, in your queries you may use these variables:

SELECT * FROM house  WHERE type = @HOUSE_SMALL_TYPE;

This method defines session variables:

If you change a session system variable, the value remains in effect until your session ends or until you change the variable to a different value. The change is not visible to other clients.

If you want to define global MySQL variables (available to all sessions):

SET GLOBAL HOUSE_SMALL_TYPE = 0;
SET GLOBAL HOUSE_MEDIUM_TYPE = 1;

To indicate explicitly that a variable is a global variable, precede its name by GLOBAL or @@global.. The SUPER privilege is required to set global variables.

Documentation:
SET statement
Using system variables
User-defined variables

5 Comments

AHa..This is exactly what I wanted. In front of HOUSE_SMALL_TYPE I added @ to make it work.
MySQL doesn't allow global user variables, only global user variables. From MySQL SET statement reference: "[GLOBAL | SESSION] system_var_name = expr". In your answer above, SET GLOBAL HOUSE_SMALL_TYPE = 0; fails for me on MySQL 5.5 with an "UNKNOWN SYSTEM VARIABLE 'HOUSE_SMALL_TYPE'" message.
"Hari's" comment should be read as: MySQL doesn't allow global user variables, only user variables
Or it should be read as MySQL doesn't allow global user variables, only global system variables
This answer has so much detail but gets a critical thing wrong. As @lepe and EzPizza point out, Mysql doesn't allow global user variables. It's unavoidable to use a table to store global variables as columns or rows in it.

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.