prevent sqldeveloper from expanding asterisc wildcard in view - oracle

I have two views, the second one depends on the data from the first and adds some columns from a different table.
In sql developer I define the views as follows:
view1:
select col11, col12, col13, col14, col15, col15, col16, col17
from table1
view2:
select view1.*, col22, col23
from view1 join table2 on view1.col11 = table2.col21
But when after saving, sqldeveloper expands the "view1.*" part of the second view to the explicit list of columns, so view2 ends up being rewritten as:
select view1.col11, view1.col12, view1.col13, view1.col14, view1.col15, view1.col15, view1.col16, view1.col17, col22, col23
from view1 join table2 on view1.col11 = table2.col21
which is harder to read and to mantain.
Is there a way to prevent this behavior?
Thanks

That's not SQL Developer doing that, it's the database.
You can create the view using the * syntax, but the database will always translate that to a fully qualified SELECT list.
CREATE VIEW LOCS
AS select * from locations;
Now ask the DB for the DDL, and you get
CREATE OR REPLACE FORCE EDITIONABLE VIEW "HR"."LOCS" (
"LOCATION_ID",
"STREET_ADDRESS",
"POSTAL_CODE",
"CITY",
"STATE_PROVINCE",
"COUNTRY_ID"
) AS
SELECT
"LOCATION_ID",
"STREET_ADDRESS",
"POSTAL_CODE",
"CITY",
"STATE_PROVINCE",
"COUNTRY_ID"
FROM
locations;
The view is defined at run-time, it'll take the existing column list and assume you want the same column names in your view as you want in the underlying objects where those columns are being pulled from.
From the Docs -
Expansion of Defining Queries at View Creation Time When a view is
created, Oracle Database expands any wildcard (*) in a top-level view
query into a column list. The resulting query is stored in the data
dictionary; any subqueries are left intact. The column names in an
expanded column list are enclosed in quote marks to account for the
possibility that the columns of the base object were originally
entered with quotes and require them for the query to be syntactically
correct.

Related

Invalid column ORA- 00904 error while inserting into table from view

In my main table having table structure column without double quotes but when in View column with double quotes. While inserting data from view into table then getting error.
Here is the table structure of tbl
create table tbl (ID number(10),
name varchar2(50),
addr varchar2(200));
While View is-
create or replace view t_view as
select "ID", "name", "addr" from tbl;
While inserting data into tbl from t_view -
insert into tbl
select * from t_view;
Then getting error ORA- 00904: "addr": Invalid identifier.
So how to resolve this issue, can i remove the double quotes from creation of view.
Remove all double quotes from everywhere in your code.
If you use them while creating objects, you'll have to use them always, specifying exactly same letter case.
Get rid of those, Oracle is - by default - case insensitive and treats all names as uppercase (but you can reference them any way you want, just don't use double quotes!).
Oracle stores the name of any object in UPPERCASE by default. If you have provided double quotes then only Oracle stores the name of the object as it is.
Double quotes - Case sensitive
No quotes - Case insensitive - Stores the name in UPPERCASE
In your case, While writing the DDL of the table, you have not provided the name of the column in double quotes so your table name and column names are stored in UPPERCASE in the metadata.
You can see the same using the following query
select table_name, column_name from user_tab_columns where table_name = 'TBL';
For giving your answer, create the view either of the following syntaxes:
create or replace view t_view as
select ID, name, addr from tbl; -- no double quotes
create or replace view t_view as
select "ID", "NAME", "ADDR" from tbl; -- UPPERCASE column names in double quotes
See the demo here
Cheers!!
What is it you are trying to accomplish. Your request just doesn't make sense. Your intended statement
insert into tbl select * from t_view;
accomplishes exactly the same thing as
insert into tbl select * from tbl;
It's not that you cann't do this (you can), but it can only cause massive duplicate data issues or (hopefully) unique constraint violations.

filter tablix without datasource values in ssrs

I have SSRS report and I need to filter a static table that I created inside the report based on parameter. There is no data source to this table and I'm entering the data manually.
The tablix contain 3 columns.
How can I filter the columns based on parameter?
I tried in the expression =#param1 for example but it doesn't work.
For now I only manage to filter if the expression is on data source fields.
Do you literally have a table with a number of values in it written directly into the report? If so I don't think you will be able to perform any filtering on it as effectively all you've done it write data into textboxes that are displayed.
I would imagine your best option would be to instead create a new dataset and populate this with your static data, e.g.
SELECT 'A' AS Letter, 'English' AS Language
UNION
SELECT 'B' AS Letter, 'French' AS Language
UNION
SELECT 'A' AS Letter, 'German' AS Language
To give you a table as follows
Letter | Language
-------+----------
A | English
B | French
A | German
That you could then filter on Letter = A
So essentially you have a Tablix that has 3 columns pre-populated with information you have manually entered into the text boxes themselves? Since you've already entered that data, I don't believe there is a way to filter that at run time. That data is hard coded in essence. The Filter ability in SSRS is used as a WHERE clause so it restricts what is brought forth into the report from the query.
I would create a data source connection to a dummy database, create a DataSet, and create a query that fills a temporary table will all the information that you've manually entered. Once you create the temporary table and inserted values into it, you can then perform a SELECT with a parameter. Your Tablix will only be populated with information that matches the parameter. Something to the effect of this:
CREATE TABLE #TempTable (
ID INT
,Name VARCHAR(MAX)
,Email VARCHAR(MAX)
)
INSERT INTO #TempTable (
ID
,Name
,Email
)
VALUES (
1
,'Bob'
,'bob#email.com'
)
,(
2
,'Frank'
,'frank#email.com'
)
,(
3
,'Jim'
,'jim#email.com'
)
SELECT
*
FROM
#TempTable
WHERE
ID = #ID
DROP TABLE #TempTable

Does updating a view affects the base table?

When I updated a view which was created using a base table, the updation affected the base table as well. How is that possible? If view is considered as just a 'window' through which we can see a set of data of the base table then how can the base table change when I try to change the data inside a view.
You can make changes to the state of underlying table using the view as long as the you are targeting the change in single table.
View is a security layer on top of table object and allows most of the DML operation as long as you do not violet the base rule.
Example:
CREATE TABLE T1
(ID INT IDENTITY(1,1), [Value] NVARCHAR(50))
CREATE TABLE T2
(ID INT IDENTITY(1,1), [Value] NVARCHAR(50))
--Dummy Insert
INSERT INTO T1 VALUES ('TestT1')
INSERT INTO T2 VALUES ('TestT2')
--Create View
CREATE VIEW V1
AS
SELECT T1.ID AS T1ID, T2.ID AS T2ID, T1.Value AS T1Value, T2.Value AS T2Value FROM T1 INNER JOIN T2
ON T2.ID = T1.ID
--Check the result
SELECT * FROM V1
--Insert is possible via view as long as it affects only one table
INSERT INTO V1 (T1Value) VALUES
('TestT1_T1')
INSERT INTO V1 (T2Value) VALUES
('TestT2_T2')
--Change is possible only if target is only one table
UPDATE V1
SET T1Value = 'Changed'--**
WHERE T2ID = 1
--This is not allowed
INSERT INTO V1 (T1Value, T2Value) VALUES
('TestT1_T1','TestT2_T2')
--Msg 4405, Level 16, State 1, Line 1
--View or function 'V1' is not updatable because the modification affects multiple base tables.
--Check T1 and T2 with each statement to see how it gets affected
--
In some databases it's possible to update the source table(s) for a view if there is a one-to-one relationship between the rows in the view and the rows in the underlying table, that is, you cant have derived columns, aggregate functions or a distinct clause in your view for example.
In Oracle, even if a view is not inherently updatable, updates may be allowed if an INSTEAD OF DML trigger is defined.
If you use mysql, you can read a detailed description about this feature Updatable and insertable views.
" If view is considered as just a 'window' through which we can see a set of data of the base table "
- Where did you get this definition?
What oracle says about views:
A view is a logical representation of another table or combination of
tables. A view derives its data from the tables on which it is based.
These tables are called base tables. Base tables might in turn be
actual tables or might be views themselves. All operations performed
on a view actually affect the base table of the view. You can use
views in almost the same way as tables. You can query, update, insert
into, and delete from views, just as you can standard tables.
Such a view into which you can update or insert are fondly named as "Updatable and Insertable Views". Oracle documentation about them is here.
Also, this is how the purpose of an "insert" statement is defined by Oracle:
Use the INSERT statement to add rows to a table, the base table of a
view, a partition of a partitioned table or a subpartition of a
composite-partitioned table, or an object table or the base table of
an object view.
Yes we can achieve the DML Operation in Views like belows:
Create or replace view emp_dept_join as Select d.department_id,
d.department_name, e.first_name, e.last_name from employees
e, departments d where e.department_id = d.department_id;
SQL>CREATE OR REPLACE TRIGGER insert_emp_dept
INSTEAD OF INSERT ON emp_dept_join DECLARE v_department_id departments.department_id%TYPE;
BEGIN
BEGIN
SELECT department_id INTO v_department_id
FROM departments
WHERE department_id = :new.department_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO departments (department_id, department_name)
VALUES (dept_sequence.nextval, :new.department_name)
RETURNING ID INTO v_department_id;
END;
INSERT INTO employees (employee_id, first_name, last_name, department_id)
VALUES(emp_sequence.nextval, :new.first_name, :new.last_name, v_department_id);
END insert_emp_dept;
/
if the viwe is defined through a simple query involving single base relation and either containing primary key or candidate key, so there will be change in base relation if changing the view. ( however there is restriction)
And updates are not allowed through view if there is multiple base relations or grouping operations.

Oracle: Is there a way to get the column data types for a view?

For a table in oracle, I can query "all_tab_columns" and get table column information, like the data type, precision, whether or not the column is nullable.
In SQL Developer or TOAD, you can click on a view in the GUI and it will spit out a list of the columns that the view returns and the same set of data (data type, precision, nullable, etc).
So my question is, is there a way to query this column definition for a view, the way you can for a table? How do the GUI tools do it?
You can use user_tab_columns (or all_tab_columns and dba_tab_columns respectively) regardless if table_name refers to a view or a table.
View columns appear in all_tab_columns, so you can query them just as you can tables.
Just simply write this query:
SQL> desc TABLE/VIEW NAME;
For example if the table/view name is "department" Then just write:
SQL> desc department;
This will give the list of all fields, it's type and default Null info of the table or view.
you can use the ANSI catalog views, should work for most RDBMs
select *
from information_schema.columns c
join information_schema.tables t on c.table_name = t.table_name
where table_type = 'view'

Creating a view using subquery,with alias for columns in ORACLE 9i!

This is my query,
CREATE VIEW employee_vu AS(
SELECT employee_id,last_name "employee",department_id
FROM employees);
I am giving alias of columns in lower case ,and in it is stored in lower case
after doing desc i have confirmed.
But when i am trying to select this column employee :error occurs
EMPLOYEE: invalid identifier
Since all column name is stored in upper case ,is this the problem,Please explain what is the concept behind!
You would need to select it using double quotes and matching case:
select employee_id, "employee", department_id from employees;
That's why creating columns with double quoted identifiers is considered bad practice in Oracle.

Resources