Error using IF statement in MySQL - mysql

I'm trying to create a mySQL Script file, so i can easily execute my changes in differente databases, but I'm having problems with a IF statement. (I'm using MySQL Workbench).
CREATE TABLE IF NOT EXISTS `build` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Version` varchar(20) NOT NULL,
`Date` datetime DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
IF EXISTS(select 1 from build where Versao = '1.1') THEN select "yes";
The create table sentence is executed correctly, but the "IF Exists(select..." statement is giving the following error:
SYNTAX ERROR: IF (if) is not a valid input at this position
The select "Yes" command will actually be replaced by an insert command. I'm just trying to test if the IF command will work.
I've also tried to put the IF EXISTS(select line in a separated query, but had the same result.
What am I doing wrong?

The SQL IF function as I imagine you want to use should be used inside a function, which you never declared.
If you want a standalone query which will behave the way you expect, then you can try this:
SELECT CASE WHEN EXISTS (SELECT 1 FROM build WHERE Versao = '1.1')
THEN "yes"
ELSE "no"
END
LIMIT 1

SQL functions can only be used inside a statement or inside a stored procedure/routine.
This SELECT statement should work for you:
SELECT IF(EXISTS(SELECT 1 FROM build WHERE Versao = '1.1'), 'yes', 'no') AS test;

Related

Idempotent table and index creation with value insertion in MySQL

I have some SQL Server schema changes that I'm trying to convert to MySQL. I know about CREATE TABLE IF NOT EXISTS in MySQL. I don't think I can use that here.
What I want to do is create a table in MySQL, with an index, and then insert some values all as part of the "if not exists" predicate. This was what I came up with, though it doesn't seem to be working:
SET #actionRowCount = 0;
SELECT COUNT(*) INTO #actionRowCount
FROM information_schema.tables
WHERE table_name = 'Action'
LIMIT 1;
IF #actionRowCount = 0 THEN
CREATE TABLE Action
(
ActionNbr INT AUTO_INCREMENT,
Description NVARCHAR(256) NOT NULL,
CONSTRAINT PK_Action PRIMARY KEY(ActionNbr)
);
CREATE INDEX IX_Action_Description
ON Action(Description);
INSERT INTO Action
(Description)
VALUES
('Activate'),
('Deactivate'),
('Specified');
END IF
I can run it once, and it'll create the table, index, and values. If I run it a second time, I get an error: Table Action already exists. I would have thought that it wouldn't run at all if the table already exists.
I use this pattern a lot when bootstrapping a schema. How can I do this in MySQL?
In mysql compound statements can only be used within stored programs, which includes the if statement as well.
Therefore, one solution is to include your code within a stored procedure.
The other solution is to use the create table if not exists ... with the separate index creation included within the table definition and using insert ignore or insert ... select ... to avoidd inserting duplicate values.
Examples of options:
Option 1:
CREATE TABLE IF NOT EXISTS `Action` (
`ActionNbr` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Description` VARCHAR(255) NOT NULL,
INDEX `IX_Action_Description` (`Description`)
) SELECT 'Activate' `Description`
UNION
SELECT 'Deactivate'
UNION
SELECT 'Specified';
Option 2:
DROP PROCEDURE IF EXISTS `sp_create_table_Action`;
DELIMITER //
CREATE PROCEDURE `sp_create_table_Action`()
BEGIN
IF NOT EXISTS(SELECT NULL
FROM `information_schema`.`TABLES` `ist`
WHERE `ist`.`table_schema` = DATABASE() AND
`ist`.`table_name` = 'Action') THEN
CREATE TABLE `Action` (
`ActionNbr` INT AUTO_INCREMENT,
`Description` NVARCHAR(255) NOT NULL,
CONSTRAINT `PK_Action` PRIMARY KEY (`ActionNbr`)
);
CREATE INDEX `IX_Action_Description`
ON `Action` (`Description`);
INSERT INTO `Action`
(`Description`)
VALUES
('Activate'),
('Deactivate'),
('Specified');
END IF;
END//
DELIMITER ;
CALL `sp_create_table_Action`;

PLS HELP MySql Error 1054: Unknown column 'column name' in field list

I have this table:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(25) NOT NULL,
`pass` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
I made a stored procedure like this:
create procedure uppdateUser(newname varchar(25), newpass varchar(50), newname2 varchar(25), newpass2 varchar(50))
-> begin
-> while name=newname && pass=newpass do
-> update users set name=newname2, pass=newpass2;
-> end while;
-> end
But I get an error unknown column name in field list when I call the procedure like this:
call uppdateUser('marky','mark','ice','cube');
I have searched questions here on StackOverflow but haven't found an answer. Can anyone explain to me what is the issue here in my query and how to fix it?
I think the issue is the references to name and pass in the while condition. Those references aren't valid. There aren't any procedure parameters or variables with those names.
It's not clear what you are trying to achieve, but I don't think there's any need for a while loop.
It looks like you want a WHERE clause on the UPDATE statement. Without a WHERE clause, the UPDATE statement is going to update every row in the table. And there's no need to run that more than once.
I'd expect the update statement to be of the form something like this:
UPDATE users
SET name = v_newname
, pass = v_newpass
WHERE name = v_oldname
AND pass = v_oldpass
But again, I don't really understand what you are trying to achieve.
First, get your UPDATE statement right. Figure out the actual SQL statements you want to execute.
Once you've got that, then you can put it into a stored procedure.

Why does MySql update ignore where clause?

I'd like to find all rows of a table with unformatted text in a specific column and re-format it. Update seems like the right choice for this but it fails. For example this table:
CREATE TABLE `test` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`));
INSERT INTO `test` (name) VALUES ('jerk'),('cad'),('slouch'),('slime');
Running the following update to add an ! to each name that doesn't contain it (but not names that do) ignores the where clause and always updates:
UPDATE test SET name = CONCAT(name, '!') WHERE LOCATE(name, '!') = 0;
Repeated application of this update keeps adding more ! to the end of name.
What's going on here and how can I do this conditional update?
EDIT: fixed typo WHERELOCATE -> WHERE LOCATE
It looks like your arguments for LOCATE are backwards. It's LOCATE(substr, str).
http://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_locate

Why does this mysql routine always returns a false in phpmyadmin sql console of XAMPP?

I just reinstalled XAMPP using this installer: xampp-win32-1.8.3-2-VC11-installer. The issue below still exists. I have saved the routine, and have called it from the phpmyadmin sql console.
Environemnt: 5.6.14 - MySQL Community Server (GPL), Apache/2.4.7 (Win32) OpenSSL/1.0.1e PHP/5.5.6
Breakdown is as follows: Trying to insert a record only if one does not previously exist. Once the record is inserted I request for that record to be returned, else return false. In the following stored procedure below I always get a false returning, even if a new record is inserted. It's like the ELSE statement is being ignored. Why is this occurring and how can it be corrected?
DROP PROCEDURE IF EXISTS `session_initiation`//
CREATE PROCEDURE `session_initiation`(
IN _user_id bigint(20),
IN _device_id bigint(20),
IN _token varchar(255)
)
BEGIN
IF NOT EXISTS
(
SELECT (1) from active_session where token = _token
)
THEN
INSERT INTO active_session (user_id, device_id, token, datetime_create, datetime_expiry ) VALUES ( _user_id, _device_id, _token, NOW(), NOW() + INTERVAL 1 DAY );
SELECT * from active_session where token = _token;
ELSE
SELECT FALSE;
END IF;
END//
I would expect if the record does not exist, that the record would be inserted and then that same record would be returned. Instead I get the record inserted, and the following being returned:
FALSE
_____
0
Appreciate anyone that can help correct my issue. I am running this directly from the SQL tab within phpmyadmin sql console.
Here are some calls to the procedure:
call session_initiation(1,1,'abc123') //inserts and returns false = 0
call session_initiation(1,1,'123abc') //inserts and returns false = 0
call session_initiation(1,1,'abc123') //returns false = 0, does not reinsert the record.
As demo-ed by #wchiquito
The solution I provided is correct in SQL Fiddle. I made slight modifications to include an primary field, which is auto_incremented.
Here are the table details:
DROP TABLE IF EXISTS `active_session`;
CREATE TABLE IF NOT EXISTS `active_session` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`device_id` bigint(20) NOT NULL,
`token` varchar(255) DEFAULT NULL,
`datetime_create` datetime DEFAULT NULL,
`datetime_expiry` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
Change:
...
IF NOT EXISTS (SELECT (1) from active_session where token = _token) THEN
...
by:
...
IF (SELECT (1) from active_session where token = _token) IS NOT NULL THEN
...
UPDATE
After creating a test SQL Fiddle the problem you describe I can not reproduce. Your code works as expected. The stored procedure does not seem to be the problem.

Mandatory field mysql

How to make sure that field is mandatory ? Here is what I mean
I have the following mysql table structure:
CREATE TABLE `new` (
`id` int(11) DEFAULT NULL,
`name` int(11) DEFAULT NULL,
`phone` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Here is query with no data for phone
insert into new values(1, 'm', '');
But the query runs fine. What should be done so that mysql returns an error if there is no data for phone field? I can do that validation by php, but I'm curious how to do that in mysql.
Possibly setting the default value of the 'phone' column to NULL would make it fail insertion because it would end up null if you did not specify it.
Otherwise you're going to need to omit the phone column for the default to kick in, say in php you'd use empty($phone) ? null : $phone; or something along those lines.
INSERT INTO new VALUES(1,'m',NULL)
will cause error.
If you want to check whether is the phone number field is a blank string,
you can use a trigger in MySQL.
I haven't tested this, but I have a feeling the '' != null. What happens if you run
insert into new(id, name) values (1, 'test');
I bet you get an insert error...
Anyway, I think its probably better to be validating in PHP than waiting till you get to the database... inserts are expensive...
'' as the 3rd option doesnt make the value of phone null.. It is just equal to a blank string thats all.
if you want to see an error, replace '' with NULL.