T-SQL how to modify the value before insert - sql-server-2008

I find that there are only after and instead of triggers in sql server. And it is illegal to modify the values in the inserted pesudo table. Then my problem occurs: If I want to check the data which is going to be inserted into my table, and when the data violates my constraints I should modify these values to default values, how to do it ? How about updateing the values after inserted ? However, if there's no primary key or colum which is unique in my table, how can I locate the row just inserted and then update it ?

Basically, with an INSTEAD OF INSERT trigger, you can achieve what you're looking for - just read out the data from the INSERTED pseudo table, modify it, and insert it into the table
So your trigger would look something like this:
CREATE TRIGGER YourTrigger ON dbo.YourTable
INSTEAD OF INSERT
AS
SET NOCOUNT ON
-- do the INSERT based on the INSERTED pseudo table, modify data as needed
INSERT INTO dbo.YourTable(Col1, Col2, ....., ColN)
SELECT
Col1, 2 * Col2, ....., N * ColN
FROM
INSERTED
Of course, you could also add e.g. checks in the form of WHERE clause to that SELECT .... FROM INSERTED statement to e.g. ignore certain rows - the possibilities are endless!

Related

IF NOT EXISTS then INSERT

I'm trying to add a value to a table but not without checking if the value already exists. This is what I have so far:
IF NOT EXISTS (
SELECT series.seriesName
FROM series
WHERE series.seriesName='Avengers'
)
BEGIN
INSERT INTO series (seriesName) VALUES 'Avengers'
END;
Database is a MySQL db on Ubuntu
You can use IGNORE keyword here.
It could look like:
INSERT IGNORE INTO series (seriesName) VALUES 'Avengers'
The important thing is to create a unique key on seriesName field as it seems that you want it to be unique.
INSERT IGNORE doesn't make the insert when key value already exists.
If you would like to be able to get id (primary key value) for row that wasn't inserted (already existed), you can do the following trick:
INSERT IGNORE INTO series (seriesName) VALUES 'Avengers'
ON DUPLICATE KEY UPDATE seriesID= LAST_INSERT_ID(seriesID)
Then you will be able to get the ID with LAST_INSERT_ID() function no matter if the row was inserted or not.

INSERT ... ON DUPLICATE KEY UPDATE how can I tell which records updated and which inserted

In a PHP script I'm using the MySQL INSERT ... ON DUPLICATE KEY UPDATE command to insert/update a number of records in my DB.
Is there anything that MySQL returns to say which records were inserted or updated?
An 'ugly' way would be to do a SELECT before each INSERT and see if the key exists before each INSERT but I'd like to know if MySQL has this function built in.
In case anyone need further info on what I'm trying to do is, to save the record id's to a log.
You will need another SELECT regardless, specifically SELECT ROW_COUNT().
From http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_row-count
For INSERT ... ON DUPLICATE KEY UPDATE statements, the affected-rows value is 1 if the row is inserted as a new row and 2 if an existing row is updated.
No, there is no way to tell which records were inserted and which were updated purely with the means provided by MySQL without additional queries. However, you can add a column to the table where you can keep an indicator that you can use to mark the record as updated instead of inserted, e.g.
INSERT INTO YourTable (Col1, Col2, Updated)
VALUES ("value1", "value2", 0)
ON DUPLICATE KEY UPDATE
Col1 = values(Col1),
Col2 = values(Col2),
Updated = 1

Trouble with MAX(col)+1 INSERT into same MySQL table

I need two id columns in the same table that create unique values upon insert. Since MySQL allows only one column to auto-increment, I need to do something like max(id)+1 for the other column.
Here's the SQL I expected to work:
INSERT INTO invoices (invoiceid)
VALUES ((SELECT MAX(invoiceid)+1 FROM invoices))
The select statement works independently, but within my INSERT, it's not allowed. I get the error : You can't specify target table 'invoices' for update in FROM clause
You want to use INSERT INTO .... SELECT FROM instead of INSERT INTO...VALUES():
INSERT INTO invoices (invoiceid)
SELECT MAX(invoiceid)+1
FROM invoices
My question for you would be why are you not use an AUTO INCREMENT field to generate the invoiceid value? That is what it is for, then you will not have to create this when inserting data.

MySQL insert on duplicate key; delete?

Is there a way of removing record on duplicate key in MySQL?
Say we have a record in the database with the specific primary key and we try to add another one with the same key - ON DUPLICATE KEY UPDATE would simply update the record, but is there an option to remove record if already exists? It is for simple in/out functionality on click of a button.
It's a work-around, but it works:
Create a new column and call it do_delete, or whatever, making it a tiny-int. Then do On Duplicate Key Update do_delete = 1;
Depending on your MySQL version/connection, you can execute multiple queries in the same statement. However, if not, just run a separate query immediately afterwords. Either way, the next query would just be: Delete From [table] Where do_delete = 1;. This way, if its a new entry, it will not delete anything. If it was not a new entry, it will then mark it for deletion then you can delete it.
Use REPLACE INTO:
replace into some_table
select somecolumn from othertable
will either insert new data or if thr same data exist will delete the data and insert the new one
The nearest possible solution for the same is REPLACE statement. Here is the documentation for REPLACE.
A similar question was asked on MySQL Forums and the recommended(and only) answer was to use REPLACE.
to be more clear with mySql:
values can be from same table:
replace into table1 (column1,column2) select (val1,val2) from table1
or
values can be from another table:
replace into table1 (column1,column2) select (val1,val2) from table2
or
values can be from any table with condition:
replace into table1 (column1,column2) select (val1,val2) from table1 where <br>column3=val3 and column4=val4 ...
or
also remember values can be static with table name for namesake:
replace into table1 (column1,column2) select (123,"xyz") from table1
no error will be thrown even if the update results in duplicate entry, as it will be replaced.
(remember) only autoincrement value will be increased;
and
if you have column with data-type "TIMESTAMP" with "on update CURRENT_TIMESTAMP", it will have no effect;
Yes of course there is a solutions in MySQL for your problem.
If you want to delete or skip the new inserting record if there already a duplicate record exists in the key column of the table, you can use IGNORE like this:
insert ignore into mytbl(id,name) values(6,'ron'),(7,'son');
Here id column is primary key in the table mytbl. This will insert multiple values in the table by deleting or skipping the new duplicate records.
Hope this will fulfill your requirement.

MYSQL: update a row without mentioning fields name

I there a way to update a row without mentioning fields name ?
I mean something like:
UPDATE table SET VALUES(1, 'name', 'family')
instead of:
UPDATE table SET id=1, name='name', family='family'
update
I'm using INSERT ON DUPLICATE KEY UPDATE and don't want to use REPLACE function because REPLACE function will cause a record to be removed, and inserted at the end, which will cause the indexing to get broken apart, decreasing the efficiency of the table.
If you specify the values in the same order as the table definition you could use
REPLACE INTO table VALUES(1, 'name', 'family');
Note that this will replace the entire row, so you must specify all the values you need!
You cannot do like that with mysql, as set clause indicates which columns to modify and the values they should be given
FYI: http://dev.mysql.com/doc/refman/5.0/en/update.html