how to remove Error for schema bindings in redshift - sql

I want to be able to make CTE to make the below SQL work, I am getting the error
ERROR: Cannot replace a normal view with a late binding view for the below SQL, any way I could change it up so that it doesnt bind with schema views?
CREATE OR REPLACE
VIEW "dev"."XXBRK_DAILY_FX_RATES" ("F_C", "CURRENCY", "C_D", "C_R") AS
SELECT DISTINCT GL.GL_R.F_C, GL.GL_R.CURRENCY,
GL.GL_R.DATE, GL.GL_R.C_R
FROM GL.GL_R
with no schema binding
WHERE GL.GL_R.C_T='Corporate'
UNION ALL
SELECT DISTINCT GL.GL_R.F_C, GL.GL_R.F_C CURRENCY, GL.GL_R.DATE, 1
FROM GL.GL_R;

So you seem to have a statement issue. The last 4 lines are after the ';' and not part of the statement being run. I'm guessing that these are extraneous and posted by mistake.
Views on Redshift come in several types - normal and late binding are 2. The view "dev"."XXBRK_DAILY_FX_RATES" seems to already exist in your cluster so your command is trying to replace it, not create it. The error message is correct, you cannot replace a view with a view of a different type. You need to drop the view, then recreate it as late binding.
Now be careful as other objects dependent on this view will be impacted when you drop it (especially if you CASCADE the drop). When you drop and recreate the view it is a new object in the database but replacing a view just make a new definition for the same object. Understand the impacts of drop to your database before you execute it.

Related

How to update a view in oracle

I have create view without any problem in Oracle. But I can not update it.I want update view in oracle, please help. Is it possible anyway?
You can create an instead of trigger on the view, as described in the documentation:
A view presents the output of a query as a table. If you want to change a view as you would change a table, you must create INSTEAD OF triggers. Instead of changing the view, they change the underlying tables.
Once you have that trigger in place, you can update the view using the same syntax as if it was a table.
You haven't shown your view or table definitions so there isn't enough information to provide a useful example; fortunately the documentation has one you can use as a starting point.
View is a select of your table my friend, there for if you want to update your view you must update your table and then you will see the changes in your view.

Views are failing when their underlying table is repopulated

I am creating a view on a bigQuery Table. The view works fine, until I truncate that table and put new data in it. I get the following error:
"Query Failed Error: A view from this query references an old version of
a table that might be incompatible. Please delete and re-create
repcore-dev:views.listings."
If I run the query that defines the view, it works. If I re-create the view with the same query, it works. But my question is why this is necessary. For us the real value in the view is that it provides an abstraction of the table data (even when that data is re-populated).

Drop a View or Table, unknowing which it is, in sqlite3

I am in a situation where I want to drop a view or table, but can only know at run-time which it is (same identifier though). This does not work:
DROP VIEW IF EXISTS my_table_or_view;
Because if my_table_or_view is a table, it will throw:
android.database.sqlite.SQLiteException: use DROP TABLE to delete table my_table_or_view
Likewise, I cannot use DROP TABLE, because it tells me to use DROP VIEW if i have a view at hand. I could catch the error, of course, but since this is part of a larger transaction, I would definitely prefer an answer that works using pure SQL (as understood by sqlite3). Any ideas?
You can get information about items in your sqlite database by SELECTing from a pseudo-table called sqlite_master.
In this case, you would do:
SELECT type FROM sqlite_master WHERE name = 'my_table_or_view'
and the resulting information will tell you whether you're dealing with a table or a view.
More info: http://www.sqlite.org/faq.html#q7

How to keep "*" in VIEW output clause so that columns track table changes?

I'm creating an Oracle view like this :
SELECT * FROM TABLE;
When I create the view, I notice that oracle changes the view query to something like :
SELECT FIELD1, FIELD2,... FROM TABLE;
My problem is that if I change the TABLE structure, add a new field for instance, the changes are not taken into consideration in the view. I have then to recreate the view, and regrant privileges on this view to the users/roles.
Is there any way to make a view mode generic and keep it as the form of : SELECT * FROM TABLE ?
Thanks.
You cannot define a simple view that would automatically change its structure when the underlying table changes. When new columns are added, you'll need to touch the view. You'll almost certainly need to do as #GordonLinoff suggests and do a CREATE OR REPLACE when the table changes. Given that changes to tables should be rare and should involve proper change control, touching the view as part of the change should be a relatively simple step.
If you're really determined to avoid having to touch the view, there are some alternatives. I generally wouldn't recommend these because they are very likely to increase rather than decrease the complexity of maintaining your system. But if you have a third party system that is generating DDL to add columns on an unpredictable basis, maybe it makes sense.
You could create a DDL trigger that fires in response to statements that ALTER the table and that submits a job using dbms_job that re-creates the view. That's quite a few moving pieces but it's generally workable.
Alternately, instead of a view, you could create a pipelined table function that returns a variable number of columns. That's going to be really complicated but it's also pretty slick. There aren't many places that I'd feel comfortable using that approach simply because there aren't many people that can look at that code and have a chance of maintaining it. But the code is pretty slick.
The * is evaluated when the view is created, not when it is executed. In fact, Oracle compiles views for faster execution. It uses the compiled code when the view is referenced. It does not just do a text substitution into the query.
The proper syntax for changing a view is:
create or replace view v_table as
select *
from table;
I have face this same issue and created a procedure which accepts the name of the table and creates the view:
str := 'create or replace view xyz.'|| tablename_in ||'_v as select * from '|| tablename_in;
execute immediate str;
Then in Toad (not sure if you use Toad), in the schema browser, right click on the table name, and then select 'Custom Queries' --> 'Edit Custom Queries' and then have it call your procedure as:
exec view_create<ObjectList>
Then you can right click on the table name and in one click create the view as Toad will pass the name of the table into the procedure.
Also in the procedure you may want to recompile the schema, so after the view is created do:
sys.utl_recomp.recomp_parallel(4, 'XYZ');
If you develop a script of some sort which can semi automate, it makes things easy.
Hope this helps...

Renaming table column and having it propagate to dependent views

If we want to change the name of MyColumnName to MyAlteredColumnName...
...and we have a SQL Server 2008 table that looks like:
MyTable
MyColumnName
and a view that references the underlying column:
CREATE VIEW MyDependentView WITH SCHEMABINDING
AS
SELECT ..., MyTable.MyColumnName
We end up following this procedure:
Dropping the View
Altering MyTable.MyColumnName to MyTable.MyAlteredColumnName
Recreating the View with a reference to MyAlteredColumnName
We do this with migrator dot net.
Is there a better way to do this? Is there T-SQL that will alter a view column name? Or any support in SQL Server 2008 for automagically tying the columns together?
Without the use of a third-party tool, this is one of the only ways to do it. You can obviously also use ALTER VIEW instead of a DROP and CREATE.
It should be noted that Red-Gate makes a tool called SQL Refactor which will automate this sort of change (no I do not work for them). I'm sure there are other similar database refactoring tools out there.
Use sp_refreshview:
EXEC sp_refreshview #viewName
If you want to refresh all your views, you'll have to iterate over a loop of them, which means dynamic SQL.
And if you layered them (a view is dependent on another view - bad), you'll have to refresh the parent first...
If it's a SELECT * view, you can call sp_refreshview, as OMG_Ponies suggested. It will recompile the view and update the column metadata appropriately. This is one area where judicious use of SELECT * could have benefits, if used appropriately within a coherent scheme.
Otherwise, you must redefine the view. Any explicit references to the old column name will now raise an error.
Ah, one more alternative:
EXEC sp_rename 'MyTable.MyColumnName', 'MyAlteredColumnName'
ALTER TABLE MyTable ADD MyColumnName AS MyAlteredColumnName
EXEC sp_rename 'MyView.MyColumnName', 'MyAlteredColumnName'
It's a hack, and it's dangerous, since the stored view definition will now be out of sync with the view metadata. And you have littered the db with superfluous computed columns.
But it will work (until you forget what you did, or someone else has to maintain the system, and things start to break mysteriously).
I use a third party tool for this, it hasn't failed me yet. It's ApexSQL Refactor, here's the how-to tutorial
How to rename a column without breaking your SQL database