Can I reference a table in a view from a stored procedure? - tsql

I've created a view on 3 tables in my database, they are as follows:
Activity
ActivityRole
aspnet_UsersInRoles
I am trying to grab the combination of what's in Activity and ActivityRole, if the UserId I pass in is a member of the role specified as required in the Activity Role.
I'm creating a view, because I want to generate an object off of the view that is called Activity that has fields from Activity and ActivityRole.
My first attempt was to create the view that INNER JOINED Activity to ActivityRole and ActivityRole to the UserRoles on Activity.ActivityId = ActivityRole.ActivityId and ActivityRole.RoleId = aspnet_UsersInRoles.RoleId
Now I want to only pull back records by a UserId located in the aspnet_User_UserRoles table.
My inclination is to write a stored procedure which does:
SELECT * From MyView WHERE aspnet_UsersInRoles.UserID = #UserID
However I cannot reference the aspnet_UsersInRoles table in the view via the stored procedure.
Is my approach totally wrong?
Thank you for any assistance.

You should look at a view as you look at a table, something with rows and columns. From the outside you see just the columns you defined in the view, not the underlying columns from the tables you created the view from. So in your case, MyView does not have a column named aspnet_UsersInRoles.UserId.
To be able to query on this column, you should include it in your view. Then you can do something like:
SELECT * FROM MyView v WHERE v.UserId = #UserId

Related

How to create materialized view of an external table

CREATE VIEW materialized_view WITH SCHEMABINDING AS
SELECT ...
FROM ext.external_table
Fails with
The option 'SCHEMABINDING' is not supported with external tables.
If I understand correctly SCHEMABINDING is necessary to make a materialized view.
How can I correct this query?
You cannot create an indexed view based on tables that are in a different database.
I think your options are:
a) create the indexed view in the other database and create a regular view in this database to query that indexed view
b) create a copy of the table in this database and a mechanism to update this table whenever the data is changed in the table which is in the other database; this could be done with triggers, replication, a stored procedure called on a schedule, etc.

Postgres View, after alter table to change table name, View still queries it?

Using Postgres database. I have an existing table, and several existing Views that query that table.
Call the table, 'contacts'.
I alter the table, changing the name to 'contacts_backup'. I then created a new table with the same name the older table used to have 'contacts'
Now it appears that if I query the existing views, the data is still retrieved from the renamed table, contacts_backup, and not the new table, 'contacts'.
Can this be? How can I update the Views to query the new table of the same name, and not the renamed contacts_backup?
My new table is actually a foreign table, but shouldn't the principle be the same? I was expecting the existing tables to query against the new table, not the old renamed one.
What is an efficient way to update the existing views to query from the new table?
This is because PostgreSQL does not store the view definition as an SQL string, but as a parsed query tree.
These parsed query trees don't contain the names of the referenced objects, but only their object identifier (oid), which does not change when you rename an object.
The same is true for table columns. This all holds for foreign tables as well.
When you examine the view definition, for example with pg_get_viewdef, the parse tree is rendered as text, so you will see the changed names.
If you want to change the table that a view is referring to, the only solution is to either DROP the view and CREATE it again, or you can use CREATE OR REPLACE VIEW.

How to allow a user to see a subset of a table or view

I have a view in a private schema with several lets say company_id's. For a special use case I want to allow one company to see a subset of this table (for its own data). So I have create a role and a schema 'company_123' and I have created a view in this schema like
create view company_123.transactions_v as
select * from business.all_transactions_v
where company_id = 123;
But unfortunately this view is empty as the user 'company_123' has no select rights on the original view. How could I achieve this requirement?
You will have to grant SELECT permissions to the user on your table.
You can slice the visible rows and columns to the user though and you should be able to solve your problem.

Table of tablenames

im using a platform called CKAN which saves datasets. When a dataset is added it creates a table with a (seemingly) random name. There are certain datasets that I want to use the data from. Therefore I want to map the relation between the table in another table and the data that is inside.
I would like to use this mapped variable (table name) in a select query as FROM statement.
SELECT * FROM (SELECT tablename FROM mappingtable WHERE id=1)
How do I do this?
Edit: As what kind of data type do I store the table name?

Convert a view to a table in PostgreSQL

I have a view view_a in my database on which several other views depend (view_b, view_c, etc.)
I need to convert view_a into a table, because I no longer want the information in this relation to be dynamic and I need the capability to edit rows manually.
Can I replace view_a with a table without doing a DROP CASCADE and redefining all views that reference view_a?
Clarification: I want view_b and view_c to continue to reference view_a (now a table). I want to replace a view with a table, not have a table in addition to a view.
I was able to resolve this without tracking down and redefining all objects that depend on view_a, at the expense of adding one level of useless redirection.
-- create a copy of the result of view_a
CREATE TABLE table_a AS SELECT * FROM view_a;
-- redefine view_a to its own result
CREATE OR REPLACE VIEW view_a AS SELECT * FROM table_a;