Teradata - How to find when was table last UPDATED not Altered - sql

I want to know how to find when was a Teradata table was last UPDATED. Everywhere I look I am getting when was it last Altered. Is updated the same as Altered?
I got the code for Alter table :
SELECT TABLENAME, LASTALTERTIMESTAMP
FROM DBC.TABLES
WHERE DATABASENAME = 'Schema'
AND TABLENAME = 'table'
ORDER BY LASTALTERTIMESTAMP DESC
What is it for UPDATE table? Thanks

Good day!
To find the time the table last was updated, you can try to parse query log table.
For example, let your table name is TNAME and it is located in schema SNAME.
So you can use the following query:
select
username,
firststeptime,
querytext
from pdcrinfo.dbqlobjtbl_hst
where
statementtype = 'Update'
and querytext like 'insert into SNAME.TNAME%'
qualify row_number() over (partition by 1 order by firststeptime desc) = 1

In terms of SQL requests, UPDATE and ALTER are two different things. ALTER modifies the table structure (DDL) -- i.e. adding / modifying a column. UPDATE modifies the table data (DML) -- i.e. adding / deleting rows.
As far as I remember, there's no easy way to see when a table was last modified (updated) unless you add some custom auditing fields (i.e. lastAlterTimestamp) that you set each time you write to the table.

IF you want to know when a table was updated, you might think about using a trigger.

Related

Copy a table data from one database to another database SQL

I have had a look at similar problems, however none of the answers helped in my case.
Just a little bit of background. I have Two databases, both have the same table with the same fields and structure. Data already exists in both tables. I want to overwrite and add to the data in db1.table from db2.table the primary ID is causing a problem with the update.
When I use the query:
USE db1;
INSERT INTO db2.table(field_id,field1,field2)
SELECT table.field_id,table.field1,table.field2
FROM table;
It works to a blank table, because none of the primary keys exist. As soon as the primary key exists it fails.
Would it be easier for me to overwrite the primary keys? or find the primary key and update the fields related to the field_id? Im really not sure how to go ahead from here. The data needs to be migrated every 5min, so possibly a stored procedure is required?
first you should try to add new records then update all records.you can create a procedure like below code
PROCEDURE sync_Data(a IN NUMBER ) IS
BEGIN
insert into db2.table
select *
from db1.table t
where t.field_id not in (select tt.field_id from db2.table tt);
begin
for t in (select * from db1.table) loop
update db2.table aa
set aa.field1 = t.field1,
aa.field2 = t.field2
where aa.field_id = t.field_id;
end loop;
end;
END sync_Data
Set IsIdentity to No in Identity Specification on the table in which you want to move data, and after executing your script, set it to Yes again
I ended up just removing the data in the new database and sending it again.
DELETE FROM db2.table WHERE db2.table.field_id != 0;
USE db1;
INSERT INTO db2.table(field_id,field1,field2)
SELECT table.field_id,table.field1,table.field2
FROM table;
Its not very efficient, but gets the job done. I couldnt figure out the syntax to correctly do an UPDATE or to change the IsIdentity field within MariaDB, so im not sure if they would work or not.
The overhead of deleting and replacing non-trivial amounts of data for an entire table will be prohibitive. That said I'd prefer to update in place (merge) over delete /replace.
USE db1;
INSERT INTO db2.table(field_id,field1,field2)
SELECT t.field_id,t.field1,t.field2
FROM table t
ON DUPLICATE KEY UPDATE field1 = t.field1, field2 = t.field2
This can be used inside a procedure and called every 5 minutes (not recommended) or you could build a trigger that fires on INSERT and UPDATE to keep the tables in sync.
INSERT INTO database1.tabledata SELECT * FROM database2.tabledata;
But you have to keep length of varchar length larger or equal to database2 and keep the same column name

How to populate dummy data into an existing table?

I have a large table with given number of rows in which I'd like to replace personal informations with dummy data. I've written functions for this but actually struggling with how to implement it.
I'd like to do something like:
ALTER TABLE SomeTable DROP COLUMN SomeName
ALTER TABLE SomeTable ADD COLUMN SomeName NVARCHAR(30) DEFAULT (SELECT * FROM dbo.FakeName)
Help would be appreciated.
Instead of dropping and adding a column, just do an UPDATE.
If you just want to update the actual data with dummy data , why can't you use update statement as below. We do almost similar in our day to day work. For ex. if we would like to sanitize actual email address of users while restoring the data in my local or test machine (in column SomeName) and in another column we just want to update it with 'XXX' .
UPDATE SomeTable
SET Email_address= SUBSTRING(Email_address,0,CHARINDEX('#',Email_address)) + '#mytest.com',
SomeName2= 'XXX',

Stored Procedure refuses to delete column that it creates

I've created a Stored Procedure that refreshes the data in a table. It first re-loads the entire table. Next, several filters are applied. (Example: the column 'Model' must equal 'W'; all rows with model 'B' are deleted.) This happens after the table has been loaded (and not during) because I want to log how many rows are deleted because of each individual filter. After the filters have been applied, some columns contain the same value in every row (the other values were deleted in the filtering process). These columns are now useless, so I want to delete them.
This seems to be problematic for SQL Server. When given the command to execute the SP, it indicates that the columns it is supposed to remove in its final step do not currently exist and refuses to run. That is technically correct, the columns currently don't exist, but they will be created by the SP itself.
Some mockup code:
CREATE PROCEDURE dbo.Procedure AS (
DROP TABLE dbo.Table
SELECT * INTO dbo.Table FROM dbo.View
INSERT INTO dbo.Log VALUES (GETDATE(),(SELECT COUNT(1) FROM dbo.Table))
DELETE FROM dbo.Table WHERE Model <> 'W'
INSERT INTO dbo.Log VALUES (GETDATE(),(SELECT COUNT(1) FROM dbo.Table))
ALTER TABLE dbo.Table DROP COLUMN Model
)
Error code when executing:
[2016-09-02 12:25:20] [S0001][207] Invalid column name 'Model'.
How do I circumvent this problem and get the SP to run?
If I understand correctly, you can use dynamic SQL:
exec sp_executesql 'ALTER TABLE dbo.Table DROP COLUMN Model';
Syntax to remove any column from table in SQL Server is
ALTER TABLE TableName DROP COLUMN ColumnName ;
This may be cause for issue.
Can you check one more time for the existency of the column 'Model' exists in the view.
because i have tried with the same scenario and its works for me..

How to change column order in a table using sql query in sql server 2005?

How to change column order in a table using SQL query in SQL Server 2005?
I want to rearrange column order in a table using SQL query.
You cannot. The column order is just a "cosmetic" thing we humans care about - to SQL Server, it's almost always absolutely irrelevant.
What SQL Server Management Studio does in the background when you change column order there is recreating the table from scratch with a new CREATE TABLE command, copying over the data from the old table, and then dropping it.
There is no SQL command to define the column ordering.
You have to explicitly list the fields in the order you want them to be returned instead of using * for the 'default' order.
original query:
select * from foobar
returns
foo bar
--- ---
1 2
now write
select bar, foo from foobar
bar foo
--- ---
2 1
according to https://learn.microsoft.com/en-us/sql/relational-databases/tables/change-column-order-in-a-table
This task is not supported using Transact-SQL statements.
Well, it can be done, using create/ copy / drop/ rename, as answered by komma8.komma1
Or you can use SQL Server Management Studio
In Object Explorer, right-click the table with columns you want to reorder and click Design (Modify in ver. 2005 SP1 or earlier)
Select the box to the left of the column name that you want to reorder. (You can select multiple columns by holding the [shift] or
the [ctrl] keys on your keyboard.)
Drag the column(s) to another location within the table.
Then click save. This method actually drops and recreates the table, so some errors might occur.
If Change Tracking option is enabled for the database and the table, you shouldn't use this method.
If it is disabled, the Prevent saving changes that require the table re-creation option should be cleared in Tools menu > Options > Designers, otherwise "Saving changes is not permitted" error will occur.
Disabling the Prevent saving changes that require the table re-creation option is strongly advised against by Microsoft, as it leads to the existing change tracking information being deleted when the table is re-created, so you should never disable this option if Change Tracking is enabled!
Problems may also arise during primary and foreign key creation.
If any of the above errors occurs, saving fails which leaves you with the original column order.
In SQLServer Management Studio:
Tools -> Options -> Designers -> Table and Database Designers
Unselect 'Prevent saving changes that require table re-creation'.
Then:
right click the table you want to re-order the columns for.
click 'Design'.
Drag the columns to the order you want.
finally, click save.
SQLServer Management studio will drop the table and recreate it using the data.
This is similar to the question on ordering the records in the result of a query .. and typically no one likes the formally correct answer ;-)
So here it goes:
as per SQL standard, the columns in a table are not "ordered"
as a result, a select * does not force the columns to be returned in a particular order
typically, each RDBMS has a kind of "default" order (usually the order that the columns were added to the table, either in the create table' or in thealter table add ` statements
therefore, if you rely on the order of columns (because you are using the results of a query to poulate some other datastructure from the position of the columns), explicitly list the columns in the order you want them.
You can of course change the order of the columns in a sql statement. However if you want to abstract tables' physical column order, you can create a view. i.e
CREATE TABLE myTable(
a int NULL,
b varchar(50) NULL,
c datetime NULL
);
CREATE VIEW vw_myTable
AS
SELECT c, a, b
FROM myTable;
select * from myTable;
a b c
- - -
select * from vw_myTable
c a b
- - -
You can do it by creating a new table, copy all the data over, drop the old table, then renaming the new one to replace the old one.
You could also add new columns to the table, copy the column by column data over, drop the old columns, then rename new columns to match the old ones. A simple example below:
http://sqlfiddle.com/#!3/67af4/1
CREATE TABLE TestTable (
Column1 INT,
Column2 VARCHAR(255)
);
GO
insert into TestTable values(1, 'Test1');
insert into TestTable values(2, 'Test2');
GO
select * from TestTable;
GO
ALTER TABLE TestTable ADD Column2_NEW VARCHAR(255);
ALTER TABLE TestTable ADD Column1_NEW INT;
GO
update TestTable
set Column1_NEW = Column1,
Column2_NEW = Column2;
GO
ALTER TABLE TestTable DROP COLUMN Column1;
ALTER TABLE TestTable DROP COLUMN Column2;
GO
sp_rename 'TestTable.Column1_NEW', 'Column1', 'COLUMN';
GO
sp_rename 'TestTable.Column2_NEW', 'Column2', 'COLUMN';
GO
select * from TestTable;
GO
In SQLServer Management Studio:
Tools -> Options -> Designers -> Table and Database Designers
Unselect Prevent saving changes that require table re-creation.
Now you can reorder the table.
Sql server internally build the script. It create a temporary table with new changes and copy the data and drop current table then recreate the table insert from temp table. I find it from "Generate Change script" option ssms 2014. Script like this. From Here: How to change column order in a table using sql query
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_emps
(
id int NULL,
ename varchar(20) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_emps SET (LOCK_ESCALATION = TABLE)
GO
IF EXISTS(SELECT * FROM dbo.emps)
EXEC('INSERT INTO dbo.Tmp_emps (id, ename)
SELECT id, ename FROM dbo.emps WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.emps
GO
EXECUTE sp_rename N'dbo.Tmp_emps', N'emps', 'OBJECT'
GO
COMMIT
If your table has enough columns then you can try this. First create a new table with preferred order of columns.
create table new as select column1,column2,column3,....columnN from table_name;
Now drop the table using drop command
drop table table_name;
now rename the newly created table to your old table name.
rename new to table_name;
now select the table, you have your columns rearranged as you preferred before.
select * from table_name;
Not sure if still relevant, but SSMS can generate a change scripts for this.
Re-order (drag the column) the table in Designer View
Click on 'Generate Change Script'
The generated script contains the script which does the following:
Create a temporary table
Adds the constraints, relationships and triggers from original table to temporary table
Drop original table
Rename temporary table to original table name
If you have not yet added any data into your table yet, there is one way to move the columns around.
Try this:
In SSMS, click Tools > Options > Designers > Table and Database Designers > Uncheck the box next to Prevent saving changes that require table re-creation > Click OK.
In the object tree, right-click on your table and select Design > in the thin column to the left of the Column Name column, you can click and drag the columns around to wherever you want them. When you're done, just go to close the Design tab and SSMS will ask you if you want to save your changes, click OK.
Optional:
3. Re-enable the checkbox for the option from Step 1 to re-secure your table.
Hope this helps someone!
Credit goes to Microsoft:
https://learn.microsoft.com/en-us/troubleshoot/sql/ssms/error-when-you-save-table#more-information
At the end of the day, you simply cannot do this in MS SQL. I recently created tables on the go (application startup) using a stored Procedure that reads from a lookup table. When I created a view that combined these with another table I had manually created earlier one (same schema, with data), It failed - simply because I was using ''Select * UNION Select * ' for the view. At the same time, if I use only those created through the stored procedure, I am successful.
In conclusion: If there is any application which depends on the order of column it is really not good programming and will for sure create problems in the future. Columns should 'feel' free to be anywhere and be used for any data process (INSERT, UPDATE, SELECT).
You can achieve it with these steps:
remove all foreign keys and primary key of the original table.
rename the original table.
using CTAS create the original table in the order you want.
drop the old table.
apply all constraints back to the original table
If the columns to be reordered have recently been created and are empty, then the columns can be deleted and re-added in the correct order.
This happened to me, extending a database manually to add new functionality, and I had missed a column out, and when I added it, the sequence was incorrect.
After finding no adequate solution here I simply corrected the table using the following kind of commands.
ALTER TABLE tablename DROP COLUMN columnname;
ALTER TABLE tablename ADD columnname columntype;
Note: only do this if you don't have data in the columns you are dropping.
People have said that column order does not matter. I regularly use SQL Server Management Studio "generate scripts" to create a text version of a database's schema. To effectively version control these scripts (git) and to compare them (WinMerge), it is imperative that the output from compatible databases is the same, and the differences highlighted are genuine database differences.
Column order does matter; but just to some people, not to everyone!
Use
SELECT * FROM TABLE1
which displays the default column order of the table.
If you want to change the order of the columns.
Specify the column name to display correspondingly
SELECT COLUMN1, COLUMN5, COLUMN4, COLUMN3, COULMN2 FROM TABLE1
you can use indexing.. After indexing, if select * from XXXX results should be as per the index, But only result set.. not structrue of Table
In order to have a specific column order You need to select column by column in the order You wish.
Selection order dictates how columns will be ordered in output.
Try this command:
alter table students modify age int(5) first;
This will change the position of age to the first position.
You can change this using SQL query. Here is sql query to change the sequence of column.
ALTER TABLE table name
CHANGE COLUMN `column1` `column1` INT(11) NOT NULL COMMENT '' AFTER `column2`;
alter table name modify columnname int(5) first;
will bring the column to first
alter table name modify columnname int(5) after (tablename);
This worked for me on Oracle DB:
select column1, column2, t.* from table t
Example: Change position of field_priority after field_price in table status.
ALTER TABLE `status` CHANGE `priority` `priority` INT(11) NULL DEFAULT NULL AFTER `price`;

How can I create a copy of an Oracle table without copying the data?

I know the statement:
create table xyz_new as select * from xyz;
Which copies the structure and the data, but what if I just want the structure?
Just use a where clause that won't select any rows:
create table xyz_new as select * from xyz where 1=0;
Limitations
The following things will not be copied to the new table:
sequences
triggers
indexes
some constraints may not be copied
materialized view logs
This also does not handle partitions
I used the method that you accepted a lot, but as someone pointed out it doesn't duplicate constraints (except for NOT NULL, I think).
A more advanced method if you want to duplicate the full structure is:
SET LONG 5000
SELECT dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME' ) FROM DUAL;
This will give you the full create statement text which you can modify as you wish for creating the new table. You would have to change the names of the table and all constraints of course.
(You could also do this in older versions using EXP/IMP, but it's much easier now.)
Edited to add
If the table you are after is in a different schema:
SELECT dbms_metadata.get_ddl( 'TABLE', 'MY_TABLE_NAME', 'OTHER_SCHEMA_NAME' ) FROM DUAL;
create table xyz_new as select * from xyz where rownum = -1;
To avoid iterate again and again and insert nothing based on the condition where 1=2
Using sql developer select the table and click on the DDL tab
You can use that code to create a new table with no data when you run it in a sql worksheet
sqldeveloper is a free to use app from oracle.
If the table has sequences or triggers the ddl will sometimes generate those for you too. You just have to be careful what order you make them in and know when to turn the triggers on or off.
You can do this
Create table New_table as select * from Old_table where 1=2 ;
but be careful
The table you create does not have any Index, PK and so on like the old_table.
DECLARE
l_ddl VARCHAR2 (32767);
BEGIN
l_ddl := REPLACE (
REPLACE (
DBMS_LOB.SUBSTR (DBMS_METADATA.get_ddl ('TABLE', 'ACTIVITY_LOG', 'OLDSCHEMA'))
, q'["OLDSCHEMA"]'
, q'["NEWSCHEMA"]'
)
, q'["OLDTABLSPACE"]'
, q'["NEWTABLESPACE"]'
);
EXECUTE IMMEDIATE l_ddl;
END;
Simply write a query like:
create table new_table as select * from old_table where 1=2;
where new_table is the name of the new table that you want to create and old_table is the name of the existing table whose structure you want to copy, this will copy only structure.
SELECT * INTO newtable
FROM oldtable
WHERE 1 = 0;
Create a new, empty table using the schema of another. Just add a WHERE clause that causes the query to return no data:
WHERE 1 = 0 or similar false conditions work, but I dislike how they look. Marginally cleaner code for Oracle 12c+ IMHO is
CREATE TABLE bar AS
SELECT *
FROM foo
FETCH FIRST 0 ROWS ONLY;
Same limitations apply: only column definitions and their nullability are copied into a new table.
If one needs to create a table (with an empty structure) just to EXCHANGE PARTITION, it is best to use the "..FOR EXCHANGE.." clause. It's available only from Oracle version 12.2 onwards though.
CREATE TABLE t1_temp FOR EXCHANGE WITH TABLE t1;
This addresses 'ORA-14097' during the 'exchange partition' seamlessly if table structures are not exactly copied by normal CTAS operation. I have seen Oracle missing some of the "DEFAULT" column and "HIDDEN" columns definitions from the original table.
ORA-14097: column type or size mismatch in ALTER TABLE EXCHANGE
PARTITION
See this for further read...
you can also do a
create table abc_new as select * from abc;
then truncate the table abc_new. Hope this will suffice your requirement.
Using pl/sql developer you can right click on the table_name either in the sql workspace or in the object explorer, than click on "view" and than click "view sql" which generates the sql script to create the table along with all the constraints, indexes, partitions etc..
Next you run the script using the new_table_name
copy without table data
create table <target_table> as select * from <source_table> where 1=2;
copy with table data
create table <target_table> as select * from <source_table>;
In other way you can get ddl of table creation from command listed below, and execute the creation.
SELECT DBMS_METADATA.GET_DDL('TYPE','OBJECT_NAME','DATA_BASE_USER') TEXT FROM DUAL
TYPE is TABLE,PROCEDURE etc.
With this command you can get majority of ddl from database objects.
Create table target_table
As
Select *
from source_table
where 1=2;
Source_table is the table u wanna copy the structure of.
create table xyz_new as select * from xyz;
-- This will create table and copy all data.
delete from xyz_new;
-- This will have same table structure but all data copied will be deleted.
If you want to overcome the limitations specified by answer:
How can I create a copy of an Oracle table without copying the data?
The task above can be completed in two simple steps.
STEP 1:
CREATE table new_table_name AS(Select * from old_table_name);
The query above creates a duplicate of a table (with contents as well).
To get the structure, delete the contents of the table using.
STEP 2:
DELETE * FROM new_table_name.
Hope this solves your problem. And thanks to the earlier posts. Gave me a lot of insight.