I have a table that has 3 columns A,B,C which has rows also. Column A is the primary key.
Now as per new requirement I need to add new column D, E and F.
Also i need to remove the previous primary key from column A and add a new primary key for column D.
Column E and F is NULL.
Please help me to create alter table statement.
What you require is a multi-step process. Adding the columns, dropping the existing primary key constraint and finally adding a new one.
The most difficult thing here is adding column D. Because you want it to be the new primary key it will have to be NOT NULL. If your table has existing data you will need to handle this error:
SQL> alter table your_table
2 add ( d number not null
3 , e date
4 , f number )
5 /
alter table your_table
*
ERROR at line 1:
ORA-01758: table must be empty to add mandatory (NOT NULL) column
SQL>
So, step 1 is add the new columns with D optional; then populate it with whatever key values:
SQL> alter table your_table
2 add ( d number
3 , e date
4 , f number )
5 /
Table altered.
SQL> update your_table
2 set d = rownum
3 /
1 row updated.
SQL>
Now we can make column D mandatory:
SQL> alter table your_table
2 modify d not null
3 /
Table altered.
SQL>
Finally, we can change the primary key column from A to D:
SQL> alter table your_table
2 drop primary key
3 /
Table altered.
SQL> alter table your_table
2 add constraint yt_pk primary key (d)
3 /
Table altered.
SQL>
For some alterations we want to add a column with a default value. In this scenario it is possible to do so in one step:
alter table your_table
add new_col varchar2(1) default 'N' not null;
In later versions of Oracle this is actually an extremely efficient of populating the new column with the same value, considerably faster than the multi-step approach outlined above.
In case it's not clear the above syntax is Oracle. I expect SQL Server will be something similar.
Related
I have a table with several columns, one of which is a CLOB containing large XML project file data. That one column accounts for 99% of the size of that table, and the table has grown to several Gb. Our DBA needs to migrate the database and wants to reduce the size as much as possible beforehand. We can't lose any rows from that table but we would be safe in clearing out the data in that particular CLOB column. Would updating the table to remove that data reduce the overall size (I assume if it did it would be in conjunction with some administrative re-indexing action or something)?
If you don't need any CLOB data, drop that column:
SQL> create table test
2 (id number,
3 cclob clob);
Table created.
SQL> insert into test (id, cclob) values (1, 'Littlefoot');
1 row created.
SQL> alter table test drop column cclob;
Table altered.
SQL>
Alternatively, create a new table with primary key column and CLOB column:
SQL> desc test
Name Null? Type
----------------------------------------- -------- ------------------
DEPTNO NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)
CCLOB CLOB
SQL> create table new_test as select deptno, cclob from test;
Table created.
SQL> alter table test drop column cclob;
Table altered.
SQL>
Now you can move the new, lightweight table to another server. If you need some of CLOB data, you can update the new table (on a new server) as
SQL> update test_on_new_server a set
2 a.cclob = (select b.cclob
3 from test_from_old_server b
4 where b.deptno = a.deptno
5 )
6 where a.loc = 'NEW YORK';
I hope to explain very well my problem
I have a new table with a Primary Key.
How to insert the table from different tables?
my problem is the one table without Primary Key and I don't know how to select from table one row and insert to the new table.
Example -
new table 1
image
AssetId is Primary key
table 2
image
I need to insert one row to table 1
table 3 image
my script -
insert AssetBusStops (AssetId,StopCode,StopId,Description,ZoneId)
select Assets.Id,stops_ppp.stop_code,stops_ppp.stop_id,stops_ppp.stop_desc,stops_ppp.zone_id from Assets inner join stops_ppp
on Assets.AssetCode = stops_ppp.stop_code
Exception -
Msg 2627, Level 14, State 1, Line 11
Violation of PRIMARY KEY constraint 'PK_AssetBusStops'. Cannot insert duplicate key in object 'dbo.AssetBusStops'. The duplicate key value is (2763).
The statement has been terminated.
The value 20001 of the column AssetCode of the table Assets matches 3 rows from the table stops_ppp and these 3 rows in the result joined query have the same value 2763 in the column id.
So your query tries to insert 3 rows, not just 1 and this would create duplicates in the primary key, which is not allowed.
You should apply a filter in the results of the query, something like:
insert AssetBusStops (AssetId,StopCode,StopId,Description,ZoneId)
select top 1 ASsets.Id,
stops_ppp.stop_code, stops_ppp.stop_id, stops_ppp.stop_desc, stops_ppp.zone_id
from Assets inner join stops_ppp
on Assets.AssetCode = stops_ppp.stop_code
order by stops_ppp.stop_code
This (for your sample data) returns only 1 row (an arbitrary ow as you requested in the comments) and can be safely inserted.
A) If you don't have FK to table AssetBusStops :
Change PK Column to IDENTITY(1,1)
Remove PK value from Insert script
B) If you have FK to table AssetBusStops :
try to use Not Exists or Merge
I have a table with a primary key, now without any reason I don't know when I am inserting data it is being loaded like this
Pk_Col Some_Other_Col
1 A
2 B
3 C
1002 D
1003 E
1901 F
Is there any way I can reset my table like below, without deleting/ truncating the table?
Pk_Col Some_Other_Col
1 A
2 B
3 C
4 D
5 E
6 F
You can't update the IDENTITY column so DELETE/INSERT is the only way. You can reseed the IDENTITY column and recreate the data, like this:
DBCC CHECKIDENT ('dbo.tbl',RESEED,0);
INSERT INTO dbo.tbl (Some_Other_Col)
SELECT Some_Other_Col
FROM (DELETE FROM tbl OUTPUT deleted.*) d;
That assumes there are no foreign keys referencing this data.
If you really, really want to have neat identity values you can write a cursor (slow but maintainable) or investigate any number of "how can I find gaps in my sequence" question on SO and perform an UPDATE accordingly (runs faster but tricky to get right). This becomes exponentially harder when you start having foreign keys pointing back to this table. Be prepared to re-run this script any time data is put into, or removed from this table.
Edit: IDENTITY columns cannot be updated per se. You can, however, SET IDENTITY_INSERT dbo.MyTable ON;, INSERT a row with the desired IDENTITY value and the values from the other columns of an existing row, then DELETE the existing row. The nett effect on the data being the same as an UPDATE.
The only sensible reason to do this is if your table has about two billion rows and you're about to run out of integers for your identity column. If that's the case you have a whole world of other stuff to worry about, too.
But seriously - listen to #Damien, don't worry about it.
ALTER TABLE #temp1
DROP CONSTRAINT PK_Id
ALTER TABLE #temp1
DROP COLUMN Id
ALTER TABLE #temp1
ADD Id int identity(1,1)
Try this one.
I have a table which contained the following columns.
ID int PK
Name nvarchar(50) NotNull
FID int FK reference to ID
ID Name PK
1 A Null
2 B Null
3 C 1
4 D 1
5 E 1
6 F 2
So, The primary key includes as a primary key in a table. I want to do that if the primary key is deleted, the rows which is contained the primary key as a foreign is deleted automatically. (example: When I delete ID 1 row, I want to delete automatically ID 3, 4, 5 rows.). How to make that the primary key is included as a foreign key in a table? How can I do this. Thanks.
You need to implement a "trigger" that does a "cascading delete".
Here's a good link:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=142564
CREATE TRIGGER test_trig
ON dbo.Table_1
FOR DELETE
AS
BEGIN
delete a from dbo.Table_2 a
JOIN
deleted d
ON a.joincol = d.joincol
END
Here are some other alternatives:
http://www.mssqltips.com/sqlservertip/1508/foreign-key-vs-trigger-referential-integrity-in-sql-server/
And here is a link to Microsoft's documentation on "Cascading Referential Integrity Constraints":
http://msdn.microsoft.com/en-us/library/ms186973.aspx
NOTE: In Microsoft SQL, a cascading delete to a self-referencing table is not allowed. You must either use a trigger, create a stored procedure, or handle the cascading delete from the calling application. An example of this is where a single table has an ID as identity and a ParentID with a relationship to ID in the same table.
see here
The only way will be to add a trigger you can refer the following links for more information.
http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/b777ec73-e168-4153-a669-835049a96520
another link
As far as I know (this page) Oracle automatically creates an index for each UNIQUE or PRIMARY KEY declaration. Is this a complete list of cases when indexes are created automatically in Oracle?
I'll try to consolidate given answers and make it community wiki.
So indexes are automatically created by Oracle for such cases:
APC: For primary key and unique key unless such indexes already exist.
APC: For LOB storage and XMLType.
Gary: For table with a nested table.
Jim Hudson: For materialized view.
Firstly, Oracle does not always create an index when we create a primary or unique key. If there is already an index on that column it will use it instead...
SQL> create table t23 (id number not null)
2 /
Table created.
SQL> create index my_manual_idx on t23 ( id )
2 /
Index created.
SQL> select index_name from user_indexes
2 where table_name = 'T23'
3 /
INDEX_NAME
------------------------------
MY_MANUAL_IDX
SQL>
... note that MY_MANUAL_IDX is not a unique index; it doesn't matter ...
SQL> alter table t23
2 add constraint t23_pk primary key (id) using index
3 /
Table altered.
SQL> select index_name from user_indexes
2 where table_name = 'T23'
3 /
INDEX_NAME
------------------------------
MY_MANUAL_IDX
SQL> drop index my_manual_idx
2 /
drop index my_manual_idx
*
ERROR at line 1:
ORA-02429: cannot drop index used for enforcement of unique/primary key
SQL>
There is another case when Oracle will automatically create an index: LOB storage....
SQL> alter table t23
2 add txt clob
3 lob (txt) store as basicfile t23_txt (tablespace users)
4 /
Table altered.
SQL> select index_name from user_indexes
2 where table_name = 'T23'
3 /
INDEX_NAME
------------------------------
MY_MANUAL_IDX
SYS_IL0000556081C00002$$
SQL>
edit
The database treats XMLType same as other LOBs...
SQL> alter table t23
2 add xmldoc xmltype
3 /
Table altered.
SQL> select index_name from user_indexes
2 where table_name = 'T23'
3 /
INDEX_NAME
------------------------------
MY_MANUAL_IDX
SYS_IL0000556081C00002$$
SYS_IL0000556081C00004$$
SQL>
No, we're getting closer but that's not quite a complete list yet.
There will also be an index automatically created when you create materialized view since Oracle needs to be able to quickly identify the rows when doing a fast refresh. For rowid based materialized views, it uses I_SNAP$_tablename. For primary key materialized views, it uses the original PK name, modified as necessary to make it unique.
create materialized view testmv
refresh force with rowid
as select * from dual;
select index_name from user_indexes where table_name = 'TESTMV';
Index Name
--------------
I_SNAP$_TESTMV
And another one, if you create a table with a nested table you get an index created automatically. Object based storage in general can do this as there can be hidden tables created.
I think schema-based XMLTypes will also do it.
Yes, that's the complete list. Oracle automatically creates an index for each UNIQUE or PRIMARY KEY declaration.