Can you create a View of a database Share, as a consumer? - snowflake-cloud-data-platform

I am trying to create a View of a database share (I am the consumer of the share).
e.g.
create view testview as (select * from myshare);
results in this error:
SQL execution error: Creating view on shared database 'myshare' is not allowed.
I didn't see any conclusive documentation around this. If this is not allowed, are there any workarounds to accomplish a similar outcome?

You cannot create a view (or any other object) in the shared database as it is read-only reflection of the providers database.
You can create a view in another [database.schema] that references it.
Heres an example using ZEPL's US_STOCK_DAILY share from the Snowflake Marketplace.
So this fails, as you have found:
Use Database US_STOCKS_DAILY;
Use Schema PUBLIC;
Create View MAX_DATE as
Select max(DATE) MAXDATE from STOCK_HISTORY;
SQL execution error: Creating view on shared database 'US_STOCKS_DAILY' is not allowed.
But this works.
Use Database MY_DATABASE ;
Use Schema MY_SCHEMA;
Create View MAX_DATE as
Select max(DATE) MAXDATE
from US_STOCKS_DAILY.PUBLIC.STOCK_HISTORY;
Select max(DATE) MAXDATE from MAX_DATE;
Note, you need to fully-qualify the object name in the providers schema.

Related

tsql: select view from different database

Is it possible to select view defined in different database in MS SQL Server?
All my searching results point to defining view to use data from different database, but haven't found if it possible to select view from another database yet.
suppose you want to do a select on database DBOther than it would be :
select * from DBOther..TableName
Also check if the table or view is on the dbo schema, if not you should add the schema also : Please notice I use only one dot now after the database name
select * from DBOther.dbo.ViewName
Make sure the Database is in the Linked Server if they are not on the same server.
Then you can access the table or view on that database via:
SELECT * FROM [AnotherServerName].[DB].[dbo].[Table]
If on same server:
SELECT * FROM [DB].[dbo].[Table]

Dynamic Row Level Security In a SQL Server Database Using Extended Properties

We have a requirement to provide customer access to a staging database so that they can extract their data into their own servers, but every table contains all customers data. All of the tables have a 'CustomerID' column. Customers should only see rows where the customerID is the same as theirs.
I am not looking for suggestions to create separate databases or views for each customer as both suggestions are high maintenance and low efficiency.
My solution has to work with:
100GB database
400 Tables
Updates every 30 minutes from the core transaction database
Quarterly schema changes (Application is in continuous Development).
Can anyone give me a definitive answer as to why the following method is not secure or will not work?:
I've set up a database user for each customer, with their customerID as an extended property.
I've created a view of every table that dynamically selects * from the table where the customerID column is the same as the extended property CustomerID of the logged in user. The code looks like this and appears to work well:
CREATE VIEW [CustomerAccessDatabase].[vw_Sales]
AS SELECT * FROM [CustomerAccessDatabase].[Sales]
WHERE [Sales].[CustomerID]=
(SELECT CONVERT(INT,p.value) AS [Value]
FROM sys.extended_properties
JOIN sys.sysusers ON extended_properties.major_id=sysusers.[uid]
AND extended_properties.name = 'CustomerID'
AND sysusers.[SID]=(SELECT suser_sid())
);
GO
To provide access to the views I've created a generic database role 'Customer_Access_Role'. This role has access granted to all of the table views, but access to the database tables themselves is denied.
To prevent users from changing their own customerID I've denied access to the extended properties like so:
USE [master];
GO
DENY EXEC ON sys.sp_addextendedproperty to [public];
GO
DENY EXEC ON sys.sp_dropextendedproperty to [public];
GO
DENY EXEC ON sys.sp_updateextendedproperty to [public];
GO
The end result is that I only need one database, and one set of permissions.
To add a new customer all I would need to do is create a new user with their customerID as an extended attribute and add them to the Customer_Access_Role. Thats it!
I am going to reiterate what everyone is stating already and sum it up.
You are making your job harder than it has to be.
Create a View, that is just their data and then give them Security access to that View.
Alternatively, extract all their data out of the "Core" database and into their own and give them the necessary access to that data.

how to use View of One DB in another DB in same server

I have View V_empmaster in MYemp database in Sqlserver2008 server, Now I want to use V_empmaster view in MASTERDB database in Same server.
My query is :
select * from dbo.MasterDB.V_empmaster;
but SQL Execution Error message is displayed
Error source: .NetSqlclientDataProvider
Error Message: Invalid objectname 'dbo.V_empmaster'
Anyone help me out what is my mistake even if it is silly
The parts of a name are server.database.schema.object. You've got schema and database the wrong way around:
select * from MasterDB.dbo.V_empmaster
When you refer view from another database in the same server, you should use three part object qualifier:
-- set context to MYemp db
use MYemp
GO
-- access V_empmaster data in MYemp db
select * from dbo.V_empmaster
GO
-- switch context to MASTERDB
use MASTERDB
GO
-- to access V_empmaster from MYemp, three part qualifier
-- ([dbName].[schemaName].[objectName]) is used
select * from MYemp.dbo.V_empmaster

How to SELECT in Oracle using a DBLINK located in a different schema?

We have an Oracle DBMS (11g) and the following configuration:
A DB user "MYUSER"
Two schemas "MYUSER" and "SCHEMA_B"
User "MYUSER" can access "SCHEMA_B" and has READ permissions on its tables
A public DB link "DB_LINK" located in "SCHEMA_B"
The DB_LINK is working when using the DB user "SCHEMA_B" directly
Question: When logged on as "MYUSER", what is the correct syntax to access tables using the DB link of "SCHEMA_B"? Is it possible to do so at all?
I already tried several constellations, which all did not work:
select * from dual#"DB_LINK"
select * from dual#"SCHEMA_B"."DB_LINK"
select * from dual#SCHEMA_B."DB_LINK"
select * from dual#SCHEMA_B.DB_LINK
select * from SCHEMA_B.dual#DB_LINK
select * from "SCHEMA_B".dual#DB_LINK
The error message I receive is:
ORA-02019. 00000 - "connection description for remote database not found"
Thanks for any suggestion!
I don't think it is possible to share a database link between more than one user but not all. They are either private (for one user only) or public (for all users).
A good way around this is to create a view in SCHEMA_B that exposes the table you want to access through the database link. This will also give you good control over who is allowed to select from the database link, as you can control the access to the view.
Do like this:
create database link db_link... as before;
create view mytable_view as select * from mytable#db_link;
grant select on mytable_view to myuser;
I had the same problem
I used the solution offered above -
I dropped the SYNONYM, created a VIEW with the same name as the synonym.
it had a select using the dblink ,
and gave GRANT SELECT to the other schema
It worked great.

Can DTS Test for Presence of MS-Access Table

I have an Access database in which I drop the table and then create the table afresh. However, I need to be able to test for the table in case the table gets dropped but not created (i.e. when someone stops the DTS package just after it starts -roll-eyes- ). If I were doing this in the SQL database I would just do:
IF (EXISTS (SELECT * FROM sysobjects WHERE name = 'Table-Name-to-look-for'))
BEGIN
drop table 'Table-Name-to-look-for'
END
But how do I do that for an Access database?
Optional answer: is there a way to have the DTS package ignore the error and just go to the next step rather than checking to see if it exists?
SQL Server 2000
I'm not sure whether you can query the system objects table in an Access database from a DTS package.
If that doesn't work, why not just try doing a SELECT * from the Access table in question and then catch the error if it fails?
Try the same T-SQL, but in MS ACCESS the sys objects table is called:
MSysObjects.
Try this:
SELECT * FROM MSysObjects WHERE Name = 'your_table';
and see if it works from there.
You can take a look at these tables if you go to Tools -> Options -> View (a tab) -> and check Hidden Objects, System Objects. So you can see both. If you open the table, you should see your table names, queries, etc. Do not change this manually or the DB could panic :)
Martin.
P.D.: Your If Exists should also check of object type:
IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id(N'[dbo].[Your_Table_Name]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
Microsoft Access has a system table called MSysObjects that contains a list of all database objects, including tables. Table objects have Type 1, 4 and 6.
It is important to reference the type:
... Where Name='TableName' And Type In (1,4,6)
Otherwise, what is returned could be a some object other than a table.

Resources