mysql - Combine 2 queries (insert and select) in 1 statement? - mysql

I have a mysql table with i (primary),s and g columns. I have 2 queries:
INSERT INTO usertable (i, s, g) VALUES('1', '2', '5') ON DUPLICATE KEY SET s=(s*g+'2')/(g+'5'), g=g+'5';
and
SELECT s FROM usertable WHERE i='1' LIMIT 1
Is it possible to have both the queries in 1 query? Basically want to reduce number DB queries.
THanks

You can perform an INSERT ON DUPLICATE KEY UPDATE (IODKU) followed by a select, that is, 2 statements. Or you can wrap them in a stored procedure and make one. Perhaps not the answer you wanted to hear.
As for the IODKU, you naturally need a unique key to facilitate the clash that triggers the UPDATE section. That unique key can be one of the following:
Primary Key (single column or composite)
non-Primary key (single column or composite) with unique keyword
Note that an upsert clash can occur on more than one unique key. All it takes is one of the unique key clashes to trigger the UPDATE section.
A single call can be achieved with one to a stored procedure such as:
call myStoredProcName(param1,param2);
Further manual page references:
INSERT ... ON DUPLICATE KEY UPDATE Syntax
Multiple-Column Indexes a.k.a. Composite Indexes
Working with Stored Procedures and CREATE PROCEDURE and CREATE FUNCTION Syntax

Related

MySQL Error: Duplicate entry 'xxx' for Primary Key

I have table MySQL with Primary Key Composed of 2 fields, as below
Already existing records in the table are:
The INSERT query I am issuing is:
When I run the query:
INSERT INTO `case_data`
VALUES ('WCD/2016/1000017', 2, '2016-09-29', 'WCD',***********************
The error message displayed is:
[Err] 1062 - Duplicate entry 'WCD/2016/1000017' for key 'PRIMARY'
Am I violating the Primary Key constraint?
Thanks in advance.
You could check if the primary key values of a row you are trying to insert already exist in a table:
SELECT COUNT(*)
FROM case_data
WHERE caseno = 'WCD/2016/1000017' AND iteration = 2;
If it returns 0 then you will not violate the PK constraint and are safe to insert the row you wish (assuming there are no additional checks, triggers, constraints). Otherwise it will return 1 which means that you already have a row with values in those columns, thus you would violate uniqueness of the row which is not allowed.
When it returns 0 just issue an INSERT command. Also, remember to specify your column tables within the statement to make sure every value from your VALUES is being put within the right column of your destination table:
INSERT INTO case_data (caseno, iteration, casedate, casetype)
VALUES ('WCD/2016/1000017', 2, '2016-09-29', 'WCD');
Avoid using backticks around your column and table names if they don't contain alternative characters like commas or spaces. This will make your code more readable and definitely speed up your writing time.

MYSQL primary key combination of 2 unique and not the same values

I have a simple MYSQL table with following columns:
first | second
first and second are integers. The primary key for the table is
PRIMARY KEY (`first`,`second`)
So this allows only a unique combination of values like:
first | second
1 | 2
2 | 1
But this key also accepts the same value for both columns. For example:
first | second
1 | 1
Is there a way to force both values to be different using MYSQL. I can do a check with PHP before inserting into the database but I'm wondering if there is a way in MYSQL to achieve it?
This restriction can't be enforced by a PRIMARY KEY or UNIQUE constraint.
Unfortunately, MySQL does not enforce CHECK CONSTRAINTS, which is what we would likely use in other databases.
To get MySQL to enforce a constraint like this, you would need to implement a BEFORE INSERT and a BEFORE UPDATE trigger.
The "trick" in the trigger body would be to detect this condition you want to restrict, e.g.
IF (NEW.first = NEW.second) THEN
And then have the trigger throw an error. In more recent versions of MySQL provide the SIGNAL statement for raising an exception. In older versions of MySQL, you'd run a statement that would throw an error (for example, performing a SELECT against a table name that is known not to exist.)
FOLLOWUP
The IF statement is valid only within the context of a MySQL stored program (for example, a PROCEDURE, FUNCTION, or TRIGGER).
To get this kind of restriction applied by an INSERT statement itself, without a constraint or trigger, we'd need to use the INSERT ... SELECT form of an INSERT statement.
For example:
INSERT INTO `mytable` (`first`, `second`)
SELECT t.first, t.second
FROM ( SELECT '1' AS `first, '1' AS `second`) t
WHERE t.first <> t.second
Since the SELECT statement returns no rows, no rows are inserted to the table.
Note that this approach applies the restriction only on this statement; This doesn't prevent some other session from performing an INSERT that doesn't enforce this restriction. To get this restriction enforced as a constraint "by the database", you'd need to implement a BEFORE INSERT and BEFORE UPDATE trigger I described earlier in the answer.

SQL add unique index in scope of two datetime's

I have an table calles SpecialOffer with productId, shopId, from , until , where the last two ones are datetime's.
I know i can do something like this
CREATE UNIQUE INDEX UniqueIndex2 ON SpecialOffer(codP, codS)
for codP to be uniq in scope of codS, but how can I accomplish this uniqueness only between 'from' and 'until' ?
You need to do this with triggers -- insert and update trigger. These can check for overlaps in the time periods.
In general, in MySQL, most constraints are handled through triggers (except for unique constraints and foreign key constraints).

Get primarys keys affected after select, update or insert only using SQL?

How to get the primary key (assuming know his name by looking show keys) resulting from an insert into?
How to get the primary keys of rows affected by an update? (as in the previous case, independent of the key name).
How to get the primary keys returned from a select query (in the query even if the key is not one of the fields surveyed).
I need to SQLs commands I run after the inserts, updates and selects in my application to obtain such information, it is possible?
My database is MySQL.
I need only sqls because i am making a logic of cache queries to aplicate in many applications (java and php) and i wish that the logic be independent of language.
example:
select name from people
i need that a query executed after this return the pk of these people
SELECT LAST_INSERT_ID();
And seriously, putting "primary key from insert mysql" into Google gets you a Stack Overflow answer as the first result.
EDIT: more discussion based on comments.
If you want to see what rows are affected by an update, just do a SELECT with the same WHERE clause and JOIN criteria as the UPDATE statement, e.g.:
UPDATE foo SET a = 5 WHERE b > 10;
SELECT id FROM foo WHERE b > 10;
If you are INSERTing into a table that does not have an auto-increment primary key, you don't need to do anything special. You already know what the new primary key is, because you set it yourself in the INSERT statement. If you want code that can handle INSERT statements coming from outside of the code that will be tracking PK changes, then you'll either need to parse the INSERT statement, or have the calling code provide information about the primary key.

Does mySql have an update/insert combo which inserts if the update fails?

I'm not optimistic that this can be done without a stored procedure, but I'm curious if the following is possible.
I want to write a single query insert/update that updates a row if it finds a match and if not inserts into the table with the values it would have been updating.
So... something like
updateInsert into table_a set n = 'foo' where p='bar';
in the event that there is no row where p='bar' it would automatically insert into table_a set n = 'foo';
EDIT:
Based on a couple of comments I see that I need to clarify that n is not a PRIMARY KEY and the table actually needs the freedom to have duplicate rows. I just have a situation where a specific entry needs to be unique... perhaps I'm just mixing metaphors in a bad way and should pull this out into a separate table where this key is unique.
I would enforce this with the table schema - utilize a unique multi-column key on the target table and use INSERT IGNORE INTO - it should throw an error on a duplicate key, but the insert will ignore on error.