Add a new column to a view in SQL - sql-server

This is my view
CREATE VIEW seat_availability AS
SELECT flightid,flightdate, maxcapacity,
FROM flight
And I want to add 2 new columns named 'bookedseats' and 'availableseats' which don't exist in any tables but are columns I need to add.
I've done my research online and some say you can alter views by using:
ALTER VIEW
And some have said that you can't do that and have to edit from the view you've just created.
I've tried this:
CREATE VIEW seat_availability AS
SELECT flightid,flightdate, maxcapacity, bookedseats varchar(10), availableseats varchar(10)
FROM flight
which gave this error:
ERROR: syntax error at or near "varchar" LINE 2: ...ECT
flightid,flightdate, maxcapacity, bookedseats varchar(10...
I've also tried ALTER VIEW:
ALTER VIEW seat_availability AS
SELECT flightid,flightdate, maxcapacity, bookedseats varchar(10), availableseats varchar(10)
FROM flight
And I got this error:
ERROR: syntax error at or near "AS" LINE 1: ALTER VIEW
seat_availability AS
It would be easy to add columns if they existed in other tables but because I need to add 2 columns that don't exist in any table, it's proving difficult to do. If someone could help it would be very appreciated. Thank you.
Perhaps I may need to drop the view? and start again with two new columns added but how do I add them since they don't exist in any table in my database??

You don't define the datatype of a column like that. You let the view use the underlying datatype like this.
ALTER VIEW seat_availability AS
SELECT flightid
, flightdate
, maxcapacity
, bookedseats
, availableseats
FROM flight
Or if you need to explicitly change the datatype you need to use CONVERT like this.
ALTER VIEW seat_availability AS
SELECT flightid
, flightdate
, maxcapacity
, bookedseats = convert(varchar(10), bookedseats)
, availableseats = convert(varchar(10), availableseats)
FROM flight

Try this to add fake columns to the view:
ALTER VIEW [dbo].[view_seat_availability]
AS
SELECT flightid
,flightdate
,maxcapacity
,CAST(NULL AS VARCHAR(10)) AS 'bookedseats'
,CAST(NULL AS VARCHAR(10)) AS 'availableseats'
FROM flight

Related

Create Table View using alises in column names

I am trying to create a view in DB2 with specific column names
so that I can compare them with another table with same column names.
My question is why this doesn't work, how to make View with column names as alises?
So, basically my idea is to have a table with different column names.
CREATE VIEW testView (
ADD_ID AS address_id,
ADD_CODE AS address_code)
AS SELECT * FROM SOP.CUST_ADDRESS;
You would code your view either like this
CREATE VIEW testView
AS SELECT
ADD_ID AS address_id
, ADD_CODE AS address_code
FROM SOP.CUST_ADDRESS;
or like this
CREATE VIEW testView (address_id, address_code )
AS SELECT
ADD_ID
, ADD_CODE
FROM SOP.CUST_ADDRESS;

How to select the default values of a table?

In my app, when letting the user enter a new record, I want to preselect the database's default values.
Let's for example take this table:
CREATE TABLE pet (
ID INT NOT NULL,
name VARCHAR(255) DEFAULT 'noname',
age INT DEFAULT 1
)
I would like to do something like this:
SELECT DEFAULT VALUES FROM pet -- NOT WORKING
And it should return:
ID | name | age
--------------------
NULL | noname | 1
I would then let the user fill in the remaining fields, or let her change one of the defaults, before she clicks on "save".
How can I select the default values of a sql server table using tsql?
You don't "SELECT" the Default values, only insert them. A SELECT returns the rows from a table, you can't SELECT the DEFAULT VALUES as there's no such row inside the table.
You could do something silly, like use a TRANSACTION and roll it back, but as ID doesn't have a default value, and you don't define a value for it with DEFAULT VALUES, it'll fail in your scenario:
CREATE TABLE pet (
ID INT NOT NULL,
name VARCHAR(255) DEFAULT 'noname',
age INT DEFAULT 1
)
GO
BEGIN TRANSACTION;
INSERT INTO dbo.pet
OUTPUT inserted.*
DEFAULT VALUES;
ROLLBACK;
Msg 515, Level 16, State 2, Line 13
Cannot insert the value NULL into column 'ID', table 'Sandbox.dbo.pet'; column does not allow nulls. INSERT fails.
You can, therefore, just supply the values for your non-NULL columns:
BEGIN TRANSACTION;
INSERT INTO dbo.pet (ID)
OUTPUT inserted.*
VALUES(1);
ROLLBACK;
Which will output the "default" values:
ID|name |age
--|------|---
1|noname|1
Selecting the default values of all columns is not very straight-forward, and as Heinzi wrote in his comment - does require a level of permissions you normally don't want your users to have.
That being said, a simple workaround would be to insert a record, select it back and display to the user, let the user decide what they want to change (if anything) and then when they submit the record - update the record (or delete the previous record and insert a new one).
That would require you to have some indication if the record was actually reviewed and updated by the user, but that's easy enough to accomplish by simply adding a bit column and setting it to 1 when updating the data.
As I have commented before. There is no need for this query since you can press alt + f1 on any table in your editor in Management Studio and provide you every information you need for the table.
select sys1.name 'Name',replace(replace(
case
when object_definition(sys1.default_object_id) is null then 'No Default Value'
else object_definition(sys1.default_object_id)
end ,'(',''),')','') 'Default value',
information_schema.columns.data_type 'Data type'
from sys.columns as sys1
left join information_schema.columns on sys1.name = information_schema.columns.column_name
where
object_id = object_id('table_name')
and information_schema.columns.table_name = 'table_name'
It seems like this might be solution:
SELECT * FROM (
SELECT
sys1.name AS COLUMN_NAME,
replace(replace(object_definition(sys1.default_object_id),'(',''),')','') AS DEFAULT_VALUE
FROM sys.columns AS sys1
LEFT JOIN information_schema.columns ON sys1.name = information_schema.columns.column_name
WHERE object_id = object_id('pet')
AND information_schema.columns.table_name = 'pet'
) AS SourceTable PIVOT(MAX(DEFAULT_VALUE) FOR COLUMN_NAME IN(ID, name, age)) AS PivotTable;
It returns:
ID |name |age
----|------|---
NULL|noname|1
Probably the column types are incorrect - but maybe I can live with that.
Thanks for #Nissus to provide an intermediate step to this.

Getting error "ORA-54033" when calling a procedure

I'm currently getting the following Oracle error when calling a procedure:
ORA-54033: column to be modified is used in a virtual column
expression
How can I track down the root cause of this error?
To find the table and column names of all virtual columns in your database you can run the following query:
SELECT c.OWNER, c.TABLE_NAME, c.COLUMN_NAME
FROM DBA_TAB_COLS c
WHERE c.VIRTUAL_COLUMN = 'YES' AND
c.OWNER NOT IN ('SYS', 'XDB')
ORDER BY c.OWNER, c.TABLE_NAME, c.COLUMN_NAME;
And you can use the following script to dump the DDL of all tables in your database which contain virtual columns to DBMS_OUTPUT:
DECLARE
lobDDL CLOB;
PROCEDURE dump_clob(aCLOB IN CLOB) IS
nCLOB_length NUMBER;
nCLOB_offset NUMBER := 1;
nMax_chunk_size NUMBER := 32767;
strChunk VARCHAR2(32767);
BEGIN
nCLOB_length := DBMS_LOB.GETLENGTH(aCLOB);
WHILE nCLOB_offset <= nCLOB_length LOOP
strChunk := DBMS_LOB.SUBSTR(aCLOB, nMax_chunk_size, nCLOB_offset);
DBMS_OUTPUT.PUT(strChunk);
nCLOB_offset := nCLOB_offset + LENGTH(strChunk);
END LOOP;
DBMS_OUTPUT.PUT_LINE(';');
END dump_clob;
BEGIN
FOR aRow IN (SELECT DISTINCT c.OWNER, c.TABLE_NAME
FROM DBA_TAB_COLS c
WHERE c.VIRTUAL_COLUMN = 'YES' AND
c.OWNER NOT IN ('SYS', 'XDB')
ORDER BY c.OWNER, c.TABLE_NAME)
LOOP
lobDDL := DBMS_METADATA.GET_DDL(object_type => 'TABLE',
name => aRow.TABLE_NAME,
schema => aRow.OWNER);
dump_clob(lobDDL);
END LOOP;
END;
I got the same error and fixed it by doing as below.
Get the hidden columns with its dependent columns using the below.
SELECT COLUMN_NAME, DATA_DEFAULT, HIDDEN_COLUMN
FROM USER_TAB_COLS
WHERE TABLE_NAME = 'YOUR_TABLE_NAME';
You should see something like this below:
SYS_STUMF_$2WEF286CDZ1WPC4V_F5 |SYS_OP_COMBINED_HASH("ID","FIRST_NAME","ANOTHER_COLUMN_NAME") | YES
Drop this hidden column by using the above column names used by it.
exec dbms_stats.drop_extended_stats(user, 'YOUR_TABLE_NAME', '("ID","FIRST_NAME","ANOTHER_COLUMN_NAME") ');
Now run your procedure or alter your columns.
alter table YOUR_TABLE_NAME modify (ID VARCHAR2(10));
Create the hidden column again:
exec dbms_stats.create_extended_stats(user, 'YOUR_TABLE_NAME', '("ID","FIRST_NAME","ANOTHER_COLUMN_NAME")');
I am just sharing my experience here with this issue.
My table has the below virtual column. There are other columns as well, and I am just adding the impacted columns here.
Create Table Virtual_test
(ColumnA varchar2(100),
CLEAN_ColumnA VARCHAR2(4000 BYTE) GENERATED ALWAYS
AS(GET_CLEAN_ColumnA(ColumnA)) VIRTUAL
);
Now when I want to modify the size of ColumnA:
Alter Table Virtual_test
MODIFY ColumnA varchar2(255);
ORA-54033: column to be modified is used in a virtual column expression.
exec dbms_stats.drop_extended_stats(USER,'Virtual_test','(GET_CLEAN_ColumnA(ColumnA))' );
Alter Table Virtual_test
MODIFY ColumnA varchar2(255);
One major mistake I did was this virtual column was not hidden and not system generated in my table.
The step dbms_stats.drop_extended_stats deleted my existing column and
dbms_stats.create_extended_stats will create an invisible column with the system generated name.
So I think this won't work with a non-hidden column, and you may need to follow the below steps and drop the column.
Alter Table Virtual_test drop column CLEAN_ColumnA;
Alter Table Virtual_test
MODIFY ColumnA varchar2(255);
Alter Table Virtual_test add
CLEAN_ColumnA VARCHAR2(4000 BYTE) GENERATED ALWAYS
AS(GET_CLEAN_ColumnA(ColumnA)) VIRTUAL;
The virtual column names starting with 'SYS_ST%' are indeed belonging to extended statistics... and since Oracle 12c, the system is trying to recognize and create them automatically...
Just google for "Oracle 12c Automatic Column Group Detection".

T-SQL: Alter View

I have a view with a field for date as a varchar. I need to change it to date time using the following code
CONVERT(DATETIME, MyDates)
This works fine when executing the view but I want to make the change permanent. I need some help with the syntax. So far I have
ALTER VIEW tableName
CONVERT(DATETIME, MyDates)
but it's obviously not working
Since a view (unless it's a materialized/indexed view which has some extra peculiarities) is more or less just a stored select query, what you do is to just change the select query and alter the view using that.
For example, if you have the view;
CREATE VIEW testview AS
SELECT id, value FROM test;
...where value is a varchar and you want it to be reflected in the view as a datetime, you can just issue;
ALTER VIEW testview AS
SELECT id, CAST(value AS DATETIME) value FROM test;
...to make it appear as a datetime in the view.
An SQLfiddle with a simple demo.
A view only fetches the data from the table as per the query.So you cannot change the datatype of the view. you have to change it in table.

Update a part of column value in SQL Server

I have a database in SQL Server with its data. I need change a part of some columns value in some conditions.
Imagine the value as "0010020001".
002 belongs to another value in my database and whenever I want to change it to 005, I must update the previous 10-digits code to "001005001".
Actually, I need to update just a part of columns value using UPDATE statement. How can I do it (in this example)?
While everyone else is correct that if you have control of the schema you should definitely not store your data this way, this is how I would solve the issue you as you described it if I couldn't adjust the schema.
IF OBJECT_ID('tempdb..#test') IS NOT NULL
DROP TABLE #test
create table #test
(
id int,
multivaluecolumn varchar(20)
)
insert #Test
select 1,'001002001'
UNION
select 2,'002004002'
UNION
select 3,'003006003'
GO
declare #oldmiddlevalue char(3)
set #oldmiddlevalue= '002'
declare #newmiddlevalue char(3)
set #newmiddlevalue = '005'
select * from #Test
Update #Test set multivaluecolumn =left(multivaluecolumn,3) + #newmiddlevalue + right(multivaluecolumn,3)
where substring(multivaluecolumn,4,3) = #oldmiddlevalue
select * from #Test
Why dont you use CSV(comma separated values) or use any other symbol like ~ to store tha values. Once you need to update a part of it use php explode function and then update it. After your work is done, concat all the values again to get the desired string to be stored in your column.
In that case your column will have values VARCHAR like 001~002~0001

Resources