In SQL it is possible to run inserts and updates against a view, as long as the view only selects data from one table. However, deletes don't seem to work quite so well. Can anyone help out?
Take this view for example:
CREATE VIEW v_MyUpdatableView
AS
SELECT x.* FROM MyPrimaryTable x
LEFT OUTER JOIN AnotherTable y ON y.MyPrimaryTableId = x.Id
I can run updates and inserts against this view and they happily pass through to MyPrimaryTable.
However, if I run a delete I receive the following exception:
View or function 'v_MyUpdatableView' is not updatable because the modification affects multiple base tables.
Quote:
DELETE statements remove data in one or more of the member tables through the partitioned view. The DELETE statements must adhere to this rule:
DELETE statements are not allowed if there is a self-join with the same view, or any of the member tables.
Data Modification Rules - Creating a Partitioned View
I would just create a stored procedure that would delete the data from two tables. I know it's not pretty, but it would work or do logical deletes, where you update a column to be "deleted".
Related
I have two different databases. Let's say 'DbOne' and 'DbTwo'.
Is there any way to do the followings?
Create a view in DbOne
Transfer data in a particular table from DbTwo to the newly created view in DbOne.
I am using SSMS and still figuring out the appropriate query..
Please give me any advice.
You need INSERT / SELECT statement - eg.
INSERT INTO DbOne..NewView
SELECT * FROM DbTwo..SourceTable
However, depending on the structure of both tables, you may need to specify the particular columns in the SELECT statement, to match the structure of the target table. (By the way, note that data is always going into a TABLE - not a VIEW. You can do an INSERT into a VIEW, but only under certain conditions)
I have to run a script for a company. I just get the same error every time.
The query:
DELETE FROM WMO
WHERE (clientnr = ****** AND number_message = *****)
The error:
ORA-01752: cannot delete from view without exactly one key-preserved
table
What did I wrong?
Thnx!
Database views are in general projection of one or more tables. It is a SELECT statement over one or more tables to be specific. For database engine it is impossible to decide what it should delete and from which table unless the view is constructed from single table.
The best solution is to run DELETE command against tables that are used to construct the view.
Additional information:
ORA-01752: cannot delete from view without exactly one key-preserved table
I get an ORA-00903 when merging into an otherwise updatable view in Oracle 11gR2 (USER_UPDATABLE_COLUMNS shows all columns insertable, updatable, deletable for base and view)
Standard Insert, Update, Delete all work normally.
The docs:
http://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_9016.htm#SQLRF01606
has the following:
Use the INTO clause to specify the target table or view you are
updating or inserting into. In order to merge data into a view, the
view must be updatable. Refer to "Notes on Updatable Views" for more
information.
The updatable view criteria appear to be met in the following example, but the ORA-00903 is present in all merge attempts. Changes to the instead of trigger don't appear to have any impact on mergability.
CREATE TABLE MERGE_TEST_B
(MERGE_TEST_ID NUMBER NOT NULL PRIMARY KEY,
MERGE_TEST_DESC VARCHAR2(50) UNIQUE NOT NULL);
CREATE OR REPLACE VIEW MERGE_TEST_V
AS
SELECT
MERGE_TEST_B.MERGE_TEST_ID,
MERGE_TEST_B.MERGE_TEST_DESC
FROM MERGE_TEST_B;
CREATE OR REPLACE TRIGGER MERGE_TEST_V_TIX
INSTEAD OF INSERT OR UPDATE OR DELETE ON MERGE_TEST_V
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('TESTING VIEW MERGE.');
END;
/
I wondered if there is a change that can can get this view into a mergable state, or whether this is ineligible.
The following attempt fails:
MERGE INTO MERGE_TEST_V
USING
(SELECT
'TESTMERGE' MERGE_TEST_DESC
FROM DUAL) TEST_DATA
ON (MERGE_TEST_V.MERGE_TEST_DESC = TEST_DATA.MERGE_TEST_DESC)
WHEN NOT MATCHED THEN INSERT
(MERGE_TEST_ID, MERGE_TEST_DESC)
VALUES
(-100, TEST_DATA.MERGE_TEST_DESC);
Any ideas would be appreciated.
Thanks
I'm not sure why Oracle returns ORA-00903 instead of ORA-38106, but the issue appears to be your trigger. Dropping the trigger will allow your merge to work.
According to the description of ORA-38106, "When using MERGE to modify a view, you must only specify a single table in the view, and the view cannot have an INSTEAD OF trigger." [emphasis mine]
Almost buried in the documentation on the merge statement, this is actually mentioned
Sometimes I found some code that makes triggers to allow user to delete from View ?
But why we need to delete from View ,, because simply we can Go to Table > and execute delete like this simple code :
delete from table where x=y ;
My question why we use deletion on views by using TRIGGERS ؟
in another words what is the advantages of using delete over a View !
The reason we use view are mainly to hide the complexity of data
sources , Hide away the actual tables (For security reasons), saving
us writing the same code over and over again.
Now if you havent let your users access the tables directly and they
only work through View in this case they will be executing Deletes
against views.
Triggers are only used when your View has more than One underlying
table. You cannot do update, insert or delete operations on view if it
effects multiple underlying tables. Therefore we make use of Instead
of Delete/Update/Insert Triggers to do these operations against
views.
When you have multiple Underlying tables if you Update,Delete or
Insert effects only One underlying table it does allow you to execute
the statement but it is not guaranteed that it will be done correctly.
therefore if you have a situation where your view is based on
multiple underlying tables you should always do update/delete/inserts
1) Directly to underlying tables. 2) Use Instead of triggers.
Also Read here for more details on why you shouldnt do update/delete/insert operations on views with multiple underlying tables.
How do i update two or more two tables without the help of where clause.
Thanks...
You can do this by using an updateable view and instead of trigger.
For this you need to create a view on your base tables and add an "instead of" trigger to this view
Later you can update the view directly.
For more information check the following links
how to update multiple tables in oracle DB?
Update multiple table column values using single query
In SQL Server you cannot update two tables in one update statement even in an updateable view.