I want to make a function that checks if ID that i will insert is unique.
This is what i did:
-- the function has to return true if ID is unique and false if ID is allready used(not unique)
CREATE OR REPLACE FUNCTION Check_uniqueID
( p_ID IN STORE."ID"%TYPE)
RETURN BOOLEAN
AS
v_IsUnique BOOLEAN := FALSE;
BEGIN
ALTER TABLE STORE
ADD CONSTRAINT check_unique_id UNIQUE (p_ID);
-- how can i programm that he returns true if its unique and false if its not?
v_IsUnique := TRUE;
RETURN v_IsUnique;
END;
Thanks in advance!
The only good practice here is to use unique constraint and sequence. Add constraint (you need to do it once):
ALTER TABLE STORE ADD CONSTRAINT check_unique_id UNIQUE (p_ID);
Create sequence for IDs (once):
create sequence my_sequence;
Use it in INSERT statements:
insert into STORE (id, another_field)
values (my_sequence.nextval, 'some value for another field');
or:
insert into STORE (id, another_field)
select my_sequence.nextval, one_more_field
from some_table;
If you don't want to use a sequence, you need to process exception ORA-00001.
Using an ALTER TABLE in a function just to check if a constraint is being violated is really bad practice. You should have the constraint on the table permanently, and handle the ORA-00001: unique constraint (constraint_name) violated exception should it be thrown. You also seem to have misunderstood the syntax of ALTER TABLE since you're trying to add a constraint on the nonexistant column of STORE.p_ID.
However, if you must use a function to reproduce functionality that the database provides via check constraints (for pre-validation in the UI or similar), this would work:
CREATE OR REPLACE FUNCTION check_uniqueid (p_id IN NUMBER)
RETURN BOOLEAN
AS
li_count PLS_INTEGER;
BEGIN
SELECT COUNT(1)
INTO li_count
FROM store s
WHERE s.id = p_id;
RETURN li_count = 0;
END;
You can use a SELECT query to check whether the value already is stored in the table.
Related
I have a table in my database with two columns, A and B.
A is the primary key, unique
B cannot be null
When I insert (newA, newB), I want to:
insert if newA doesn't exist
ignore if (newA, newB) already exists (no errors, no effect or overwrite same/existing pair)
return an error if a different couple exists with A = newA
This looks really simple, but I don't really see how to do that! I guess one way would be to set the primary key as (A,B), would that do it?
You can try this:
Create unique key (A, B). This will not allow the record with the same (A, B) combination to be inserted
Use INSERT IGNORE instead of INSERT so unique constrain you created on step 1 will not cause an error but will be silently ignored.
Manually check existence record with the same A value in before insert/update triggers and throw an error if such record already there. Something like this:
CREATE TRIGGER `tbl_before_insert` BEFORE INSERT ON `tbl` FOR EACH ROW BEGIN
IF EXISTS(SELECT * FROM `tbl` WHERE `tbl`.`A` = NEW.`A` AND `tbl`.`B` != NEW.`B`) THEN
SET #msg = CONCAT('Record with A=', NEW.A, ' already exists');
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = #msg;
END IF;
END
You can keep A as the Primary Key while making the B field UNIQUE.
Existing A Insert => It will throw an error (as it is the primary key).
If new A, new B => It won't be a problem.
If new A, old B => Because we made the B column unique, It'll throw an error.
Looking back at my old pending questions, the answer here is quite simple:
make (A,B) the key
create an index on A to make it unique
This will enforce the desired rules.
I am trying to solve the problem with insert new value into table. Primary key is ID not email... Before insert i need check other records for email value. If no one match inserted email, data is inserted. But i canot write correct code for that...
IF EXIST (SELECT email FROM users WHERE email = "email")
THEN
BEGIN
'We Have Records of this Customer'
END
ELSE
BEGIN
INSERT INTO users
VALUES (null,'email9','password9','forename9','lastname9')
END
END IF
Or:
IF SELECT COUNT(*) FROM users WHERE email = 'email' > 0
THEN
BEGIN
//email exist
END
ELSE
BEGIN
//inserting
END
END IF
This looks like a good use case for MySQL INSERT ... ON DUPLICATE KEY UPDATE syntax.
First of all, you want to create a UNIQUE constraint on column email. This is the proper way to represent your business rule:
ALTER TABLE users ADD CONSTRAINT users_unique_email UNIQUE (email);
Now, if the record that is about to be inserted would generate a duplicate on the primary key or on that UNIQUE constraint, then MySQL lets you turn the operation to an UPDATE instead.
In your case, since you want not to update anything in that case, you can simply re-assign the email column (which we know is the same here).
Consider:
INSERT INTO users
VALUES (null,'email9','password9','forename9','lastname9')
ON DUPLICATE KEY UPDATE SET email = 'mail9';
I cant comment, but I post this. I recommend making an external script like in python or java to do this for you by selecting * and parsing through the output because SQL itself does not have the power to do this.
I am currently setting up a few different tables for which I have to use certain constraints. I have been getting on okay but I am stuck with the following:
Limiting the 'Country' column to a choice between UK, USA and Australia
Creating the 'ImageFilename' column so that each record must have an extension of .JPG
Is there a specific constraint for these examples or is it a case of thinking outside the box here? I've tried to think of ways to use the current constraints I know but I'm stumped.
Any help would be much appreciated! Thanks in advance.
edit: would it perhaps be a CHECK constraint?
As of MySQL 8.0, MySQL doesn't support CHECK constraints.
Even if MySQL were to add support for CHECK constraints, I wouldn't use that as a solution, because when you eventually add New Zealand and Canada, or if you support .PNG in addition to .JPG, you'd have to redefine the constraints.
For the countries I would create a lookup table, and a foreign key constraint to restrict your country column.
CREATE TABLE Countries ( Country VARCHAR(75) PRIMARY KEY );
ALTER TABLE DifferentTable ADD FOREIGN KEY (Country) REFERENCES Countries(Country);
This allows you to support new countries simply by INSERTing a new country name into the Countries table.
For the image extension, I can think of two alternatives:
Define a trigger that throws a SIGNAL if the filename doesn't match the right extension.
CREATE TRIGGER ImageFilenameIns BEFORE INSERT ON DifferentTable
FOR EACH ROW
BEGIN
IF (SUBSTRING_INDEX(NEW.ImageFilename, -1) <> '.JPG') THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'You must use a .JPG filename';
END IF;
END
CREATE TRIGGER ImageFilenameUpd BEFORE UPDATE ON DifferentTable
FOR EACH ROW
BEGIN
IF (SUBSTRING_INDEX(NEW.ImageFilename, -1) <> '.JPG') THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'You must use a .JPG filename';
END IF;
END
Remember to set DELIMITER if you create this trigger using the mysql client or SQL script.
Using the trigger solution requires redefining the trigger if you someday want to support .PNG or other extensions.
Define a generated column to represent the file extension, and make sure that references a lookup table of allowed file extensions.
CREATE TABLE ImageFileExtensions ( Extension VARCHAR(3) PRIMARY KEY );
INSERT INTO ImageFileExtensions (Extension) VALUES ('JPG');
ALTER TABLE DifferentTable
ADD COLUMN ImageFilenameExtension VARCHAR(3) AS (SUBSTRING_INDEX(ImageFilename, -1)) STORED,
ADD FOREIGN KEY(ImageFilenameExtension) REFERENCES ImageFileExtensions(Extension);
With the latter solution, you can add support for a new file extension simply by INSERTing a new extension into the ImageFileExtensions table.
I'm not sure what is that you try to pull off but you can use IF in mysql:
* (for Creating):
CREATE TABLE IF NOT EXISTS
:row(row_id varchar(8) NOT NULL,
:country varchar(25) NOT NULL CHECK (country IN ('USA','UK','Australia')),
PRIMARY KEY (row_id));
Test whether two strings are the same and return "YES" if they are, or "NO" if not (for Selecting):
SELECT IF(STRCMP(":country","UK") = 0, "YES", "NO");
or:
SELECT :row, CASE :Country
WHEN 'USA' THEN 1
WHEN 'UK' THEN 2
WHEN 'Australia' THEN 3
ELSE 'NO'
END AS :row1, :row2, :row3
FROM :Table
but still you can do the same thing with PHP:
$country = $_GET['country'];
switch($country){
case "UK":
case "USA":
case "Australia":
Model::DB->Post($country, "Country");
break;
default:
App::Error->Err("Invalid input - " . $country);
}
I'm using MySQL Workbench (6.3) and I'm trying to create a stored procedure with a specific "INSERT IF NOT EXSISTS" but I think I don't do it well. By the way, I did read this topic http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html and tried both examples, it didn't work. Here is the statement :
CREATE DEFINER=`test`#`localhost` PROCEDURE `onPlayerJoin`(
IN uuid CHAR(36),
IN nickname CHAR(16),
IN firstConnection TIMESTAMP,
IN lastConnection TIMESTAMP
)
BEGIN
INSERT IGNORE INTO `test`.`player` (`playerUuid`, `playerNickname`, `playerFirstConnection`, `playerLastConnection`)
VALUES (uuid, nickname, firstConnection, lastConnection);
UPDATE `test`.`player` SET
`playerNickname` = nickname,
`playerLastConnection` = lastConnection
WHERE `playerUuid` = uuid;
END
IF the PK isn't found, INSERT it. ELSE, UPDATE certain columns. (that I can specified) However, it seems that it updates every column, which I would like to restrict to certain columns. Here is my procedure : http://pastebin.com/NfcdU9Rb !
Optional question : is it injection-safe ?
Use INSERT ... ON DUPLICATE KEY UPDATE Syntax
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
Kindly refer the link for details:
http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
I need to create a query to insert some records, the record must be unique. If it exists I need the recorded ID else if it doesnt exist I want insert it and get the new ID. I wrote that query but it doesnt work.
SELECT id FROM tags WHERE slug = 'category_x'
WHERE NO EXISTS (INSERT INTO tags('name', 'slug') VALUES('Category X','category_x'));
It's called UPSERT (i.e. UPdate or inSERT).
INSERT INTO tags
('name', 'slug')
VALUES('Category X','category_x')
ON DUPLICATE KEY UPDATE
'slug' = 'category_x'
MySql Reference: 13.2.5.3. INSERT ... ON DUPLICATE KEY UPDATE Syntax
Try something like...
IF (NOT EXISTS (SELECT id FROM tags WHERE slug = 'category_x'))
BEGIN
INSERT INTO tags('name', 'slug') VALUES('Category X','category_x');
END
ELSE
BEGIN
SELECT id FROM tags WHERE slug = 'category_x'
END
But you can leave the ELSE part and SELECT the id, this way the query will always return the id, irrespective of the insert...
MySQL has nice REPLACE. It is easy to use and remember it's syntax as same as INSERT.
in you case, just run following query.
REPLACE INTO tags('name', 'slug') VALUES('Category X','category_x')
It acts like INSERT when no unique constraint violation. If duplicated value found on PK or UNIQUE key, then other columns will be UPDATED with given values. It is done by DELETE duplicated record and INSERT new record.