Changing data on SQL - sql

If I put new column or new value on rows, does it change the data on the database that I'm using to query the data? Let's say I have database 'A' and I'm working with table 'B'. Then, if I decide to put a new column on table 'B', will this also change the whole table 'B' from database 'A'? Or will this only show on the result tab, without changing the real data?

DDL makes changes to database. Like if you are doing
ALTER TABLE table_name
ADD column_name datatype
Yes, it will update in database.
As you mentioned you just started learning so possibly you are fetching records in new column while selecting. Like
SELECT table_name.column + table_name.column2 AS new_column_name, table_name.column, table_name.column2
FROM table_name
In above case it will not make any change in database.

Related

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

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.

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',

Oracle : 2 column names for a single column

There is a requirement to rename the DB tables and column names,
so all the tools/application taking data from the source will have to change their queries. The solution we are planning to implement is that for every table name change we will create a VIEW with the original table name. Easy and simple to implement. No query change required, but there are cases where a table name remains the same but a column name changes within the table, so we can't create another view (any object with the same object name).
Is there a Column Synonym kind of thing which we can propose here?
Any solutions/ideas are welcome. Requirement is to have queries containing original column names referring to the new columns in the same tables.
For example:
Table Name: DATA_TABLE
Existing Column Name: PM_DATE_TIME
New Column Name: PM_DATETIME
Existing Query select pm_Date_time from Data_Table; should refer to new column pm_Datetime
You could consider renaming your original table, and then create a View in its place providing both the old and the new column-names:
CREATE TABLE Data_Table ( pm_Date_time DATE );
ALTER TABLE Data_Table RENAME TO Data_Table_;
CREATE VIEW Data_Table AS
(
SELECT pm_Date_time,
pm_Date_time AS pm_Datetime -- Alias to provide the new column name
FROM Data_table_
);
-- You can use both the old columnn-name...
INSERT INTO Data_Table( pm_Date_time ) VALUES ( SYSDATE );
-- ... or the new one
UPDATE Data_Table SET pm_Datetime = SYSDATE;
There are things that won't work the same way as before:
-- INSERT without stating column-names will fail.
INSERT INTO Data_Table VALUES ( SYSDATE );
-- SELECT * will return both columns (should not do this anyway)
SELECT * FROM Data_Table
Once you are done with your changes drop the view and rename the table and the columns.
You'll want to add virtual columns:
ALTER TABLE Data_Table ADD pm_Date_time as (pm_Datetime);
UPDATE: Oracle (11g at least) doesn't accept this and raises "ORA-54016: Invalid column expression was specified". Please use Peter Lang's solution, where he pseudo-adds zero days:
ALTER TABLE Data_Table ADD (pm_Datetime + 0) AS pm_Date_time;
This works like a view; when accessing pm_Date_time you are really accessing pm_Datetime.
Rextester demo: http://rextester.com/NPWFEW17776
And Peter is also right in this point that you can use it in queries, but not in INSERT/columns or UPDATE/SET clauses.
This was basically touched on in the answer by Thorsten Kettner, but what your looking for is a pseudocolumn.
This solution looks a little hacky because the syntax for a pseudocolumn requires an expression. The simplest expression I can think of is the case statement below. Let me know if you can make it more simple.
ALTER TABLE <<tablename>> ADD (
<<new_column_name>> AS (
CASE
WHEN 1=1 THEN <<tablename>>.<<old_column_name>>
END)
);
This strategy basically creates a new column on the fly by evaluating the case statement and copying the value of <old_column_name> to <new_column_name>. Because you are dynamically interpolating this column there is a performance penalty vs just selecting the original column.
One gotcha here is that this will only work if you are duplicating a column once. Multiple pseudocolumns cannot contain duplicate expressions in Oracle.
we cant create a another view (any object with the same object name).
That's true within a schema. Another somewhat messy approach is to create a new user/schema with appropriate privileges and create all your views in that, with those querying the modified tables in the original schema. You could include instead-of triggers if you need to do more than query. They would only need the old columns names (as aliases), not the new ones, so inserts that don't specify the columns (which is bad, of course) would still work too.
You could also create synonyms to packages etc. in the original schema if the applications/tools call any and their specifications haven't changed. And if they have changed you can create wrapper packages in your new schema.
Then your legacy tools/applications can connect to that new schema and if it's all set up right will see things apparently as they were before. That could potentially be done by setting current_schema, perhaps through a login trigger, if the way they connect or the account they connect to can't be modified.
As the tools and applications are upgraded to work with the new table/column names they can switch back to the original schema.

sql - retain calculated result in calculated field

certain fields in our database contain calculated functions e.g.
select lastname + ', ' + firstname as fullname from contact where contact.id =$contact$
when viewing the field the correct data is shown (i assume this is because when you open the record, the calculation is executed). however, the data is not 'stored' to the field, and therefore is null until the record is opened. is it possible to 'store' the result to the field, making it possible to search the data?
many thanks
james
EDIT
it is not possible for me to create computed_columns using our software.
the above field is a text feild where either 1) a user can manual type in the required data or 2) the database can generate the answer for you (but only whilst you are looking at the record). i know that if I run the following:
Select * from contact where contact.id =$contact$ for xml auto
i only get lastname, firstname - so i know that the fullname field does not retain its information.
If you are using computed columns in sql server, the column is already searchable regardless of whether the calculation result is stored or not. However, if you would like to make it so that the calculation is not run each time you read the row, you can change that under row properties in your Modify Table GUI.
Use the PERSISTED key word when you create the column
From BOL:
PERSISTED
Specifies that the SQL Server Database Engine will physically store the computed values in the table, and update the values when any other columns on which the computed column depends are updated. Marking a computed column as PERSISTED lets you create an index on a computed column that is deterministic, but not precise. For more information, see Creating Indexes on Computed Columns. Any computed columns that are used as partitioning columns of a partitioned table must be explicitly marked PERSISTED. computed_column_expression must be deterministic when PERSISTED is specified.
This isn't the way computed columns work in SQL Server, so I suspect this is something your client application is doing. How are you looking at the data when the value is computed correctly? Does it work when you view the data in SSMS?
Take a look at http://msdn.microsoft.com/en-us/library/ms191250(v=SQL.90).aspx to see how to create computed columns properly.
eg.
create table TestTable
(a int,
b int,
c as a + b)
insert into TestTable (a,b)
values (1,2)
select * from TestTable
where c = 3
This query is based on the computed column and it returns the row that's been inserted.
You need to use the PERSISTED option on a column when you use CREATE TABLE e.g.
CREATE TABLE test (col_a INT, col_b INT, col_c AS col_A * col_B PERSISTED)

Syntax Difference in Table Alter/Add with and without a NULL

I have a question, but let me first say that this is being performed on a database which I inherited and I am currently trying to improve the design on. Also the reason for the syntax is the fact that there are a lot of tables that the datatypes have been 'tweaked' by tech support people (/facepalm) causing lots of issues.
IF NOT EXISTS(Select *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'RXINFO'
AND TABLE_SCHEMA = N'scriptassist'
AND COLUMN_NAME = N'Price')
BEGIN
Alter Table [scriptassist].[RXINFO] Add [Price] FLOAT
Print 'Price Field nonexistant creating this field'
END
ELSE
BEGIN
If Not Exists(Select *
From Information_Schema.Columns
Where Table_Name = N'RXINFO'
And Table_Schema = N'scriptassist'
And Column_Name = N'Price'
And DATA_Type = N'FLOAT'
AND IsNull(CHARACTER_MAXIMUM_LENGTH, 0) = 0)
BEGIN
Alter Table [scriptassist].[RXINFO] Alter Column Price FLOAT
Print 'Price Field needed type updating'
END
END
Is what I am currently doing to determine if a column needs to be altered or added to a database. However even in the case of only having to add say 3-4 columns on a 500K-750K line database, where the table is about 100 columns wide, I'm estimating that this is taking anywhere from 15-20 minutes per column.
Things I have done to try to speed it up:
Removed the indexes before and then re-add after
Single user mode
ensured no connection to the database other than mine
I still don't feel like it should be taking as long as it is, so my question is do I need to explicitly add the NULL after the column type for this to work as fast as I think it should?
If you specifiy "NULL" or perhaps 'NOT NULL WITH DEFAULT 0.0" then only the schema will be updated and the rows in the table will not be altered, so the change will sub second for each table.
If the column is NULLable it doesn't have to be there so there is no need to update the rows when you alter the schema.
If the column is not NULLable without a default then when you ALTER the schema to add the column every row in the existing table will be updated to add a column with the default default value of 0.0. This is why your alters take minutes.
If you specify 'NOT NULL WITH DEFAULT' then the "DEFAULT" is added when the row is read so again there is no need to update the table rows.
In both cases the current INSERT/UPDATE SQL will work without any changes. If you add a "NOT NULL" column with no default then current update SQLs will bomb out unless you add in the price column. This could be good thing or a bad thing depending on what you want to achieve.