How to know new value of primary key in UPDATE trigger? (T-SQL) - tsql

I have a table:
CREATE TABLE Demo (
id uniqueidentifier PRIMARY KEY
);
I want to create an AFTER UPDATE (or INSTEAD OF UPDATE) trigger, and I need to know OLD and NEW values of "id" column inside the trigger.
Is it possible to do this?

No. This isn't possible.
If the table has 2 rows and you update both of them there is no way of knowing which row in INSERTED maps to which in DELETED.
You can use the OUTPUT clause for this (outside a trigger) though.
Or you could add an IDENTITY column to the table and use that to join INSERTED and DELETED (it is not permitted to update identity columns so that gives you something immutable)

Related

Before Update Trigger in Phpmyadmin how to get updated values

I'm trying to get a trigger in phpmyadmin which would create a audit with a certain column value (reputation) before and after the update of a specific table.
Something like:
CREATE DEFINER=`test`#`%`
TRIGGER `monitor update reputation`
BEFORE UPDATE ON `game_resorts`
FOR EACH ROW
INSERT INTO `audit` (`id`, `datetime`, `id_resort`, `reputation`)
VALUES (NULL, CURRENT_TIMESTAMP, id_resort, reputation)
The main question is how can I retrieve the id_resort which will be updated; and then, the reputation value?
In MySQL, you would use the NEW keyword, so I assume it would be the same using phpmyadmin.
For example:
CREATE DEFINER=`test`#`%`
TRIGGER `monitor_update_reputation` //don't use spaces in a trigger name
BEFORE UPDATE ON `game_resorts`
FOR EACH ROW
INSERT INTO `audit` (`datetime`, `id_resort`, `reputation`)
VALUES (CURRENT_TIMESTAMP, NEW.id_resort, NEW.reputation)
If you want to get the value of id_resort or reputation before the update, you can use the OLD keyword:
...
VALUES (CURRENT_TIMESTAMP, OLD.id_resort, OLD.reputation)
Also, I don't think you can insert NULL into a primary key column. If your id on the audit table is set to auto increment, you can simply omit the id column from the INSERT statement.

What's the proper way to block a table from further insert ? Postgresql

My table has three rows and i don't want to add any more rows.
However i want to be able to select & update on the table.
What is the best way to block further inserts ?
Assuming you have a primary key named id with the current values 1,2 and 3 you could do something like this:
alter table the_table
add constraint limit_values check (id in (1,2,3));
Now if you try to insert a new row, you either get a primary key violation (because 1,2 and 3 already exist) or you get a check constraint violation when you try to insert a different ID value that does not yet exist.

How to INSERT OR UPDATE while MATCHING a non Primary Key without updating existing Primary Key?

I'm currently working with Firebird and attempting to utilize UPDATE OR INSERT functionality in order to solve a particular new case within our software. Basically, we are needing to pull data off of a source and put it into an existing table and then update that data at regular intervals and adding any new references. The source is not a database so it isn't a matter of using MERGE to link the two tables (unless we make a separate table and then merge it, but that seems unnecessary).
The problem rests on the fact we cannot use the primary key of the existing table for matching, because we need to match based off of the ID we get from the source. We can use the MATCHING clause no problem but the issue becomes that the primary key of the existing table will be updated to the next key every time because it has to be in the query because of the insertion chance. Here is the query (along with c# parameter additions) to demonstrate the problem.
UPDATE OR INSERT INTO existingtable (PrimaryKey, UniqueSourceID, Data) VALUES (?,?,?) MATCHING (UniqueSourceID);
this.AddInParameter("PrimaryKey", FbDbType.Integer, itemID);
this.AddInParameter("UniqueSourceID", FbDbType.Integer, source.id);
this.AddInParameter("Data", FbDbType.SmallInt, source.data);
Problem is shown that every time the UPDATE triggers, the primary key will also change to the next incremented key I need a way to leave the primary key alone when updating, but if it is inserting I need to insert it.
Do not generate primary key manually, let a trigger generate it when nessesary:
CREATE SEQUENCE seq_existingtable;
SET TERM ^ ;
CREATE TRIGGER Gen_PK FOR existingtable
ACTIVE BEFORE INSERT
AS
BEGIN
IF(NEW.PrimaryKey IS NULL)THEN NEW.PrimaryKey = NEXT VALUE FOR seq_existingtable;
END^
SET TERM ; ^
Now you can omit the PK field from your statement:
UPDATE OR INSERT INTO existingtable (UniqueSourceID, Data) VALUES (?,?) MATCHING (UniqueSourceID);
and when the insert is triggered by the statement then the trigger will take care of creating the PK. If you need to know the generated PK then use the RETURNING clause of the UPDATE OR INSERT statement.

T-SQL create table with primary keys

Hello I wan to create a new table based on another one and create primary keys as well.
Currently this is how I'm doing it. Table B has no primary keys defined. But I would like to create them in table A. Is there a way using this select top 0 statement to do that? Or do I need to do an ALTER TABLE after I created tableA?
Thanks
select TOP 0 *
INTO [tableA]
FROM [tableB]
SELECT INTO does not support copying any of the indexes, constraints, triggers or even computed columns and other table properties, aside from the IDENTITY property (as long as you don't apply an expression to the IDENTITY column.
So, you will have to add the constraints after the table has been created and populated.
The short answer is NO. SELECT INTO will always create a HEAP table and, according to Books Online:
Indexes, constraints, and triggers defined in the source table are not
transferred to the new table, nor can they be specified in the
SELECT...INTO statement. If these objects are required, you must
create them after executing the SELECT...INTO statement.
So, after executing SELECT INTO you need to execute an ALTER TABLE or CREATE UNIQUE INDEX in order to add a primary key.
Also, if dbo.TableB does not already have an IDENTITY column (or if it does and you want to leave it out for some reason), and you need to create an artificial primary key column (rather than use an existing column in dbo.TableB to serve as the new primary key), you could use the IDENTITY function to create a candidate key column. But you still have to add the constraint to TableA after the fact to make it a primary key, since just the IDENTITY function/property alone does not make it so.
-- This statement will create a HEAP table
SELECT Col1, Col2, IDENTITY(INT,1,1) Col3
INTO dbo.MyTable
FROM dbo.AnotherTable;
-- This statement will create a clustered PK
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable_Col3 PRIMARY KEY (Col3);

Prevent insertion if the records already exist in sqlite

I am programming for iPhone and i am using SQLITE DB for my app.I have a situation where i want to insert records into the table,only if the records doesn't exist previously.Otherwise the records should not get inserted.
How can i do this?Please any body suggest me a suitable query for this.
Thank you one and all,
Looking at SQLite's INSERT page http://www.sqlite.org/lang_insert.html.
You can do it using the following syntax
INSERT OR IGNORE INTO tablename ....
Example
INSERT OR IGNORE INTO tablename(id, value, data) VALUES(2, 4562, 'Sample Data');
Note : You need to have a KEY on the table columns which uniquely identify a row. It is only if a duplicate KEY is tried to be inserted that INSERT OR IGNORE will not insert a new row.
In the above example if you have a KEY on id, then another row with id = 2 will not be inserted.
If you have a KEY only on id and value then a combination of id = 2 and value = 4562 will cause a new row not be inserted.
In short there must be a key to uniquely identify a ROW only then will the Database know there is a duplicate which SHOULD NOT Be allowed.
Otherwise if you do not have a KEY you would need to go the SELECT and then check if a row is already there, route. But here also whichever condition you are using on columns you can add them as a KEY to the table and simply use the INSERT OR IGNORE
In SQLite it is not possible to ALTER the table and add a constraint like UNIQUE or PRIMAY KEY. For that you need to recreate the table. Look at this FAQ on sqlite.org
http://sqlite.org/faq.html#q11
Hello Sankar what you can do is perform a select query with the record you wish to insert and then check the response via SQLite's SQLITE_NOTFOUND flag you can check whether that record already exists or not. If it doesn't exist you can insert it otherwise you skip inserting.
I hope this is helpful.