I have to create a schema for Oracle and another one for SQL Server. Is it better to use alter table to modify default value (date), or should I use a trigger, since Oracle uses SYSDATE and SQL Server uses GETDATE()
I think generally it would be better use a default value, without using trigger (my opinion is to use triggers only if strictly necessary). Moreover, trigger difference between MSSQL and ORACLE requests more attention than using DEFAULT SYSDATE rather than DEFAULT GETDATE().
On the other hand, default value will be used ONLY if you don't pass any value with insert command: with trigger you can change values as you want.
I'm facing with similar problem (we have two DB version, MSSSQL and ORACLE, for the same application) and in this case we use DEFAULT value for insert date (eg. column DATA_INS) and trigger for update date (column DATA_UPD) of a record.
Related
I'm porting a SQL Server based app to Oracle. Our Oracle DBA has given me a schema that was supposed to be identical to the original SQL Server schema (and generated from it), but the auto generated keys are missing. I am trying to alter these table PK's from a normal INT to incrementing. I am doing so with Oracle SQL Developer 4.0.3 and Oracle 12c.
The error I receive is ORA-01442: column to be modified to NOT NULL is already NOT NULL
I get this after editing the table, selecting the column and setting it's Identity dropdown to 'Generated as Identity'. I am not sure why SQl Developer is attempting to make it not null when it's already a PK.
My questions are: Is this the proper way to setup a generated key? How can I get around this? If I go alter all the required columns, can the DBA use the schema to regenerate whatever procedure he used to create it in the first place to allow proper generated keys and is there a better solution for creating a good schema to go forward with?
Thanks.
If the column is already definied as NOT NULL there is no need to re-defined it as NOT NULL. Therefore you get the error ora-01442.
The best way to obtain sequence values, such as identity in SQL Server, is define the column with default sequence, before inserting row:
CREATE SEQUENCE SEQ_NAME
START WITH 1
INCREMENT BY 1
NOCACHE
NOCYCLE;
ALTER TABLE table_name MODIFY column_name INT DEFAULT SEQ_NAME.NEXTVAL;
PD: This DEFAULT works with 12 c. To 11g or less, you must create a trigger
I've almost seen every post concerning this question but haven't captured the best one. Some of them recommend using Identity but some triggers to perform incrementing integer column.
I'd like also to use triggers as there will be more delete happen in my table in this case. In addition, as I have mainly come from Interbase DBMS where I used to create a before insert trigger on table this issue sucks until now as I migrated from Interbase to MS SQL Server.
This is how I did in Interbase
CREATE trigger currency_bi for currency
active before insert position 0
AS
declare variable m integer;
begin
select max(id)+1 from currency into :m;
if (:m is NULL ) then m=1;
new.id=:m;
end
So, as I should frequently use this, which is the best way to create a trigger that increments integer column using max(id)+1 ?
Don't use triggers to do this, it will either kill the performance or cause all sorts of concurrency problems, depending on your use of transactions and locking.
It's better to use one of mechanisms available in the engine -- identity property or sequence object.
If you're running a newer version of SQL Server, with sequence feature available, use sequence. It will allow you to reserve a range of ids from the client applcation, and assign them to new rows on the client, before sending them to server for insert.
Always use Identity option , because as you told that you frequently delete the record, in this case trigger will some time give wrong information ( Called Isolation level).
Suppose one transaction delete the highest one record and just before or same time your trigger fired. So it get the deleted highest record which is not exist after few second.
So when you fired select query, it show the gap which is wrong.
Sqlserver give the inbuilt mechanism of this type of situation with auto identity true option.
http://mrbool.com/understanding-auto-increment-in-sql-server/29171
You donot bother about this. Also draw back of trigger is if multiple insert happened, then it always fired after the last insert statement.
Try to never use trigger , as it is harmful and not controllable.
Still if you want , then add in your insert statement , not use trigger
How can I auto-increment a column without using IDENTITY?
On some of my tables I have some columns which contain a creation timestamp column that is supposed to be set on insert and a last update timestamp that is supposed to be updated on every update. I would like to do this without using a trigger is that possible?
For creation time column you can set default yo NOW, but for last update time I think you will have to use trigger.
Btw. why you don't want triggers?
I've got a new website moved to my server. This website uses PHP and MySQL, and is built very poorly.
The problem is - it needs non-null values inserted into new records where ever I don't specify a value, though the default value is null.
I've been told it has been done on the previous server, but they have no idea how. I'd be glad to receive some help on this.
You could update the default values of the fields of your database to prevent problems using:
ALTER TABLE `table` ALTER `field` SET DEFAULT 'value'
More information on ALTER TABLE for specific fields and parameters can be found in the documentation.
You need to add default values for the columns, either recreate the tables with defaults or alter the table definitions.
http://dev.mysql.com/doc/refman/5.1/en/alter-table.html
http://dev.mysql.com/doc/refman/5.1/en/create-table.html
Is it possible to force a column in a SQL Server 2005 table to a certain value regardless of the value used in an insert or update statement is? Basically, there is a bug in an application that I don't have access to that is trying to insert a date of 1/1/0001 into a datetime column. This is producing a SqlDateTime overflow exception. Since this column isn't even used for anything, I'd like to somehow update the constraints on the columns or something in the database to avoid the error. This is obviously just a temporary emergency patch to avoid the problem... Ideas welcome...
How is the value being inserted? If it's through a stored proc... you could just modify the Sproc to ignore that input parameter.
if it's through client-side generated SQL, or an ORM tool, otoh, then afaik, the only option is a "Before" Trigger that "replaces" the value with an acceptable one...
If you're using SQL 2005 you can create an INSTEAD OF trigger.
The code in this trigger wil run in stead of the original insert/update
-Edoode
I'd create a trigger to check and change the value
If it is a third party application then I will assume you don't have access to the Stored Procedure, or logic used to generate and insert that value (it is still worth checking the SPs for the application's database though, to see if you can modify them).
As Charles suggested, if you don't have access to the source, then you need to have a trigger on the insert.
The Microsoft article here will give you some in depth information on creating triggers.
However, SQL Server doesn't have a true 'before insert' trigger (to my knowledge), so you need to try INSTEAD OF. Have a look here for more information. In that article, pay particular note of section 37.7, and the following example (again from that article):
CREATE TRIGGER T_InsertInventory ON CurrentInventory
INSTEAD OF INSERT AS
BEGIN
INSERT INTO Inventory (PartNumber, Description, QtyOnOrder, QtyInStock)
SELECT PartNumber, Description, QtyOnOrder, QtyInStock
FROM inserted
END
Nick.
the simplest hack would be to make it a varchar, and let it insert that as a string into the column.
The more complicated answer is, you can massage the data with a trigger, but it would still have to be valid in the first place. For instance I can reset a fields value in an update/insert trigger, but it would still have to get through the insert first.