Check if a row exists using MySQL 8 version - mysql

I have this query in MySQL database 8.0.12 version
mysql> SELECT tTbl INTO #tTbl FROM t_table WHERE tTbl = "t_contents_1_2021";
SELECT #tTbl;
Query OK, 1 row affected (0.07 sec)
+-------------------+
| #tTbl |
+-------------------+
| t_contents_1_2021 |
+-------------------+
1 row in set (0.07 sec)
Now I need test whether a row exists in a MySQL table or not, using exists condition.
The exists condition can be used with subquery.
It returns true when row exists in the table, otherwise false is returned. True is represented in the form of 1 and false is represented as 0.
I have tried without success
mysql> SELECT EXISTS(SELECT tTbl INTO #tTbl FROM t_table
WHERE tTbl = "t_contents_1_2021");
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 '(SELECT tTbl INTO #tTbl FROM t_table
WHERE tTbl' at line 1
mysql>
How to do resolve this?

SELECT .. INTO does not return the rowset. EXISTS needs in rowset. So SELECT .. INTO cannot be used in EXISTS.
Remove it:
SELECT EXISTS ( SELECT tTbl
FROM t_table
WHERE tTbl = "t_contents_1_2021" );
If you need both check the row existence and save the value to the variable then use inline assigning:
SELECT EXISTS ( SELECT NULL
FROM t_table
WHERE (#tTbl := tTbl) = "t_contents_1_2021" );

Related

MySQL require a minimum length

I'm using MySQL Workbench and I made a table called 'organizations' and want to block any try of adding a value to a column with less than 5 letters.
The column name is 'namee'.
I made this, but I get an error:
ALTER TABLE organizations
ADD CONSTRAINT MINIMO CHECK (LENGTH(namee) >= 5);
Error:
Error Code: 3814. An expression of a check constraint 'MINIMO' contains disallowed function: `LEN`.
Based on the error message you shared, you apparently tried to use a function LEN(). No built-in function of that name exists in MySQL.
Testing with MySQL 8.0.21, I can reproduce the error you showed if I try using LEN() or any other nonexistent function.
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.21 |
+-----------+
1 row in set (0.00 sec)
mysql> ALTER TABLE organizations ADD CONSTRAINT MINIMO CHECK (LEN(namee) >= 5);
ERROR 3814 (HY000): An expression of a check constraint 'MINIMO' contains disallowed function: `LEN`.
mysql> ALTER TABLE organizations ADD CONSTRAINT MINIMO CHECK (BOGUS(namee) >= 5);
ERROR 3814 (HY000): An expression of a check constraint 'MINIMO' contains disallowed function: `BOGUS`.
If you had tried to define a stored function called LEN() and use that, you should read https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html:
Stored functions and user-defined functions are not permitted.
But LENGTH() works without error. By the way, I'd recommend to use CHAR_LENGTH() so multibyte characters are counted as one character.
mysql> ALTER TABLE organizations ADD CONSTRAINT MINIMO CHECK (CHAR_LENGTH(namee) >= 5);
Query OK, 1 row affected (0.04 sec)
Records: 1 Duplicates: 0 Warnings: 0
That seems odd. Does this work?
ALTER TABLE organizations
ADD CONSTRAINT MINIMO CHECK (LENGTH(namee) LIKE '_____');
I suspect that LENGTH() is non-deterministic; I am not sure why this would be.
At least in older versions, and you didn't specify which version, a trigger is needed for checking length.
CREATE TRIGGER t1 BEFORE INSERT ON organizations
FOR EACH ROW BEGIN
DECLARE numLength INT;
SET numLength = (SELECT LENGTH(NEW. namee));
IF (numLength > 30) THEN
SET NEW.col = 1/0;
END IF;
END;
Consider the following...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table (my_string VARCHAR(20) NOT NULL);
SET #string = 'red';
INSERT INTO my_table SELECT #string FROM (SELECT 1)x WHERE CHAR_LENGTH(#string) >= 5;
SET #string = 'orange';
INSERT INTO my_table SELECT #string FROM (SELECT 1)x WHERE CHAR_LENGTH(#string) >= 5;
SELECT * FROM my_table;
+-----------+
| my_string |
+-----------+
| orange |
+-----------+
I am not sure which version you are using but it works fine for me on MYSQL 8.x
create table test_check(name varchar(10));
ALTER TABLE test_check
ADD CONSTRAINT MINIMO CHECK (LENGTH(name) >= 5);

Error writing trigger statement

I would like to limit the size of a table to X rows (I'll use 5 for example). When the limit is reached, I want to copy the oldest row to another table, then delete it. I currently have:
CREATE TRIGGER LimitRows BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
IF (SELECT COUNT(*) FROM MyTable) >= 5 THEN
INSERT INTO HistoryTable
SELECT *
FROM MyTable A
WHERE vhID = A.min(vhID);
DELETE FROM MyTable
WHERE vhID = min(vhID);
END IF;
END;
Currently, I get the error:
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 8
How do I write this trigger correctly? Also, how can I modify to cut the table down to 5 rows if it starts out at something like 100 rows?
You need to change the delimiter first
delimiter |
CREATE TRIGGER LimitRows BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
IF (SELECT COUNT(*) FROM MyTable) >= 5 THEN
INSERT INTO HistoryTable
SELECT *
FROM MyTable A
WHERE vhID = A.min(vhID);
DELETE FROM MyTable
WHERE vhID = min(vhID);
END IF;
END
|
delimiter ;
Otherwise the trigger definition would end at the first ; which would make it incomplete.

MySQL if statement fails

I have a function called tableExists. It can be used to check for the existence of a table. I want to use it in a DB upgrade script. I can use the function like this:
select myDb.tableExists('myDb', 'someTable') as cnt into #exists;
And see the results like this:
mysql> select #exists;
+---------+
| #exists |
+---------+
| 1 |
+---------+
Now, I want to use it in an If statement, followed by a create table statement. But, I am having problems with the if. The following is what I am trying to test with:
mysql> IF (#exists = 1) THEN
-> select 'exists'
-> END IF;
ERROR 1064 (42000): 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 'IF (#exists = 1) THEN
select 'exists'
END IF' at line 1
What am I missing here? This should be simple.
You can only use the IF inside a stored procedure.
The valid select statement would be:
SELECT CASE (#exists) WHEN 1 THEN 'exists' END as DoesItExist
If you use the case as a stand alone element in a stored proc, you'll need to end it with end case how ever.
Why don't you just use IF NOT EXISTS in the CREATE TABLE query and save yourself all this trouble:
CREATE TABLE new_table IF NOT EXISTS
... {table definition}
If the table already exists, nothing will happen.

Why does this SQL injection succeed even though the SQL statement produces a syntax error?

In this question and some of the comments, this input:
$input = '; DELETE FROM table_name ; #';
was suggested as an example of an SQL injection into this PHP statement:
$input = $_POST['input'];
'SELECT '.$input.' FROM table_name'
I cut into the chase and used an example in MySQL directly, although I used * in place of #. The result is the same.
CREATE TABLE a_table (
id INT NOT NULL);
INSERT INTO a_table (id) VALUES (1), (2), (3), (4), (5);
SELECT * FROM a_table;
SELECT ; DELETE FROM a_table; * FROM a_table;
SELECT COUNT(*) FROM a_table;
This outputs:
mysql> SELECT * FROM a_table;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.00 sec)
mysql> SELECT ; DELETE FROM a_table; * FROM a_table;
ERROR 1064 (42000): 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 1
Query OK, 5 rows affected (0.03 sec)
mysql> SELECT * FROM a_table;
Empty set (0.00 sec)
Why does this SQL injection succeed despite the syntax error? Is this because MySQL parses and runs the DELETE query before the surrounding SELECT query? I don't plan to rely on such weak PHP code or MySQL syntax errors to guard against SQL injection, of course; this example just intrigued me.
The queries are still run because mysql uses ; to delimit each query and it will continue running the queries even when there is a syntax error if you allow it to do so. Running the queries in SequelPro I get a message about the syntax error and it prompts me if I want to continue running all queries or stop. However, running them straight in MySQL commandline the queries continue running and MySQL just gives an error message and continues to the next query as expected (same thing that happens with the PHP code).

MySql Select Case to select datafrom tables

I want to select data from one of the tables in the database, on the basis of the parameter.
Here's what I did.
DELIMITER $$
CREATE PROCEDURE `myDB`.`Temp`(
IN ID INT(11)
)
BEGIN
SELECT CASE
WHEN ID IN(1,2) THEN
SELECT * FROM table1;
WHEN ID IN(3,4) THEN
SELECT * FROM table2;
END CASE;
END$$
DELIMITER ;
But. I'm getting error:
Error Code : 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 'SELECT * FROM table1;
WHEN ID IN(3,4) THEN
SELECT * FROM table2;
END' at line 7
You can not use subquery inside case when you can use if else clauses.
IF(ID IN(1,2)) THEN
SELECT * FROM table1;
ELSEIF(ID IN(3,4)) THEN
SELECT * FROM table2;
END IF;
select * from table1 where id in (1,2)
union all
select * from table2 where id in (3,4)
although the column count has to the same across both tables for this to work (and in any case it is not at all bad practice to name the columns in the SELECT to avoid confusion, bahaviour-creep and so on).