People,
I need migrate a Oracle trigger to SQL server, but I could not do.
The trigger in Oracle is very simple:
CREATE OR REPLACE TRIGGER trigger_teste
BEFORE INSERT OR UPDATE
ON teste
FOR EACH ROW
DECLARE
BEGIN
:new.id := (coalesce(:NEW.id, 0));
:new.vlr_sal := (coalesce(:NEW.vlr_sal, 0.00));
END;
I tried several ways but none successfully!
Thank for help!
My T-SQL is a bit rusty, but something like this should work. Note that SQL server does not have row level triggers, only statement level triggers.
CREATE TRIGGER trigger_teste
ON teste
BEFORE INSERT OR UPDATE
AS
update inserted
set id = coalesce(id, 0),
vlr_sal = coalesce(vlr_sal, 0.0)
GO
(Not sure if I got missed a semicolon or not. I never understood when SQL Server needs or deosn't need one)
See the manual for more details:
http://msdn.microsoft.com/en-US/library/ms189799%28v=sql.90%29
http://msdn.microsoft.com/en-US/library/ms191300%28v=sql.90%29
This is not an appropriate use of triggers in any flavour of RDBMS. The SQL standard allows us to define default values when we create the table using the DEFAULT constraint syntax. Both Oracle and SQL Server have this.
Obviously you haven't do this when you created the table. The good news is we can use ALTER TABLE to add default constraints. Something like this
alter table teste
alter column id set default 0
That's for SQL Server. In Oracle it would be:
alter table teste
modify id default 0
As the nameless equine points out, a complete replacement for the trigger must include NOT NULL constraints on the affected columns. If the existing table lacks not null constraints we can add them using the same syntax as shown above, replacing the DEFAULT clause with NOT NULL - or even combining the two clauses in the same statement.
Related
I have a migration script with the following statement:
ALTER TABLE [Tasks] ALTER COLUMN [SortOrder] int NOT NULL
What will happen if I run that twice? Will it change anything the second time? MS SQL Management Studio just reports "Command(s) completed successfully", but with no details on whether they actually did anything.
If it's not already idempotent, how do I make it so?
I would say that second time, SQL Server checks metadata and do nothing because nothing has changed.
But if you don't like possibility of multiple execution you can add simple condition to your script:
CREATE TABLE Tasks(SortOrder VARCHAR(100));
IF NOT EXISTS (SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE [TABLE_NAME] = 'Tasks'
AND [COLUMN_NAME] = 'SortOrder'
AND IS_NULLABLE = 'NO'
AND DATA_TYPE = 'INT')
BEGIN
ALTER TABLE [Tasks] ALTER COLUMN [SortOrder] INT NOT NULL
END
SqlFiddleDemo
When you execute it the second time, the query gets executed but since the table is already altered, there is no effect. So it makes no effect on the table.
No change is there when the script executes twice.
Here is a good MSDN read about: Inside ALTER TABLE
Let's look at what SQL Server does internally when performing an ALTER
TABLE command. SQL Server can carry out an ALTER TABLE command in any
of three ways:
SQL Server might need to change only metadata.
SQL Server might need to examine all the existing data to make sure
it's compatible with the change but then change only metadata.
SQL Server might need to physically change every row.
I've been comparing databases using vs 2010 scheme comparing tool and it generated some stuff which is not clear. For example at the end of the script it has this statement:
ALTER TABLE [dbo].[My_table] WITH CHECK CHECK CONSTRAINT [FK_FOREIGN_ID];
Can anyone explain what this means?
It means that existing data should be checked against the constraint when it is added.
Failure to have the CHECK CHECK leaves your constraints untrusted and they cannot be used by the query optimiser.
That tells SQL Server to validate the constraint against new rows. The counter example would be to use WITH NOCHECK to temporarily disable validation checks for new rows.
ALTER TABLE (Transact-SQL) (WITH CHECK | WITH NOCHECK )
Can you add a column to a table inserting it in between two existing columns in SQL Server without dropping and re-creating the table?
Mediumly long answer, yes (ish) but it's ugly and you probably wouldn't want to do it.
please note: this code creates a physical table
CREATE TABLE MyTest (a int, b int, d int, e int)
INSERT INTO MyTest (a,b,d,e) VALUES(1,2,4,5)
SELECT * FROM MyTest
ALTER TABLE MyTest ADD c int
ALTER TABLE MyTest ADD d_new int
ALTER TABLE MyTest ADD e_new int
UPDATE MyTest SET d_new = d, e_new = e
ALTER TABLE MyTest DROP COLUMN d
ALTER TABLE MyTest DROP COLUMN e
EXEC SP_RENAME 'MyTest.d_new', 'd';
EXEC SP_RENAME 'MyTest.e_new', 'e';
SELECT * FROM MyTest
DROP TABLE MyTest
The simple answer is no. Is there a reason why column order is important to you?
Yes you can add here is the query for your concern:
ALTER table table_name ADD column column_name(new) datatype AFTER column_name
Take a look at this link:
http://www.bobsgear.com/display/ts/Adding+Column+After+Another+Column+-+SQL+Server+2005
As you can see, the answer is:
'not possible without moving data to a temp table'
which is what the SQL Server Management Studio actually does.
yes. You can drag and drop it in design mode, or copy and paste it in edit table mode
in response to comments, yes, this is with SQL Server Management Studio through the UI, and under the hood, it's doing the drop/recreate you're trying to avoid, so no, you can't do it without the server doing it for you.
This is possible in SQL Server Management Studio (SSMS).
Filter your table in Object Explorer and right click on the table > Design
Drag the arrow highlighted in the left to move your column.
First answer, no.
Second answer, according to this thread http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=58912, found via Can I logically reorder columns in a table?, you could create the column then reorder the columns in the table by editing the system tables. But it looks incredibly messy and I would not trust that things would not break.
For Mysql yes For SQL server No
also it's not a good practice to add column in between as it can hamper some queries if you are relying on the table schema in your project.
I have an application that uses a SQL Server database with several instances of the database...test, prod, etc... I am making some application changes and one of the changes involves changing a column from a nvarchar(max) to a nvarchar(200) so that I can add a unique constraint on it. SQL Server tells me that this requires dropping the table and recreating it.
I want to put together a script that will do the table drop, recreate it with the new schema, and then reinsert the data that was there previously all in one go, if possible, just to keep things simple for use when I migrate this change to production.
There is probably a good SQL Server way to do this but I'm just not aware of it. If I was using Mysql I would mysqldump the table and its contents, and use that as my script for applying that change to production. I can't find any export functionality in SQL server that will give me a text file consisting of inserts for all data in a table.
Use SQL Server's Generate Scripts command
right click on the database; Tasks -> Generate Scripts
select your tables, click Next
click the Advanced button
find Types of data to script - choose Schema and Data.
you can then choose to save to file, or put in new query window.
results in INSERT statements for all table data selected in bullet 2.
No need to script
here are two ways
1 use alter table ....alter column.....
example..you have to do 1 column at a time
create table Test(SomeColumn nvarchar(max))
go
alter table Test alter column SomeColumn nvarchar(200)
go
2 dump into a new table while converting the column
select <columns except for the columns you want to change>,
convert(nvarchar(200),YourColumn) as YourColumn
into SomeNewTable
from OldTable
drop old table
rename this table to the same table as the old table
EXEC sp_rename 'SomeNewTable', 'OldTable';
Now add your index
Is there a parallel in Microsoft SQL Server (2005, preferably) for the Oracle functionality of setting a column to be unused? For example:
ALTER TABLE Person SET UNUSED Nickname;
Nothing turns up in searches, so my thought is this feature must be Oracle specific.
Don't think there's anything like that in SQL server.
You could create a 1:1 relation to a new table containing the hidden columns:
insert into NewTable
select (keycol, Nickname) from ExistingTable
alter table ExistingTable drop column Nickname
That way you still have the data, but the column is in a table nobody knows about.
Alternatively, you could use column level permissions:
DENY SELECT (Nickname) ON ExistingTable TO domain\user
DENY SELECT (Nickname) ON ExistingTable TO public
...
This will return an error when someone tries to read the column. The big disadvantage of this method is that select * will also fail.
There is no equivalent statement, but depending on your need you could probably write a trigger to roll back any changes if made.