I am trying to associate an object (table) back to the user that created it. Since objects are owned by the active role, how can I get a list of tables created by a single user? I've searched QUERY_HISTORY for the create table statements, but looking for a better solution.
Does something like this help or is this what you are doing now? I think it's the main solution available right now. You can, of course, change the filters as desired including filtering by a specific user or timeframe.
use role accountadmin;
use schema snowflake.account_usage;
select q.start_time created_time, q.user_name, t.table_name, q.query_text, t.table_schema schemas_name, T.table_catalog database_name from query_history q
inner join tables t
on q.start_time = t.created
and q.schema_name = t.table_schema
and q.database_name = t.table_catalog
and q.query_text ilike 'create%table%'
and q.start_time > '2020-11-04 11:13:54'
order by q.start_time;
You should be able to do it with a query like this
use schema snowflake.account_usage;
select *
from QUERY_HISTORY
where
database_name = 'TPCDS'
and query_type = 'CREATE'
;
Related
I need to find all the different database tables used in views.
I tried information_schema.view_table_usage.
I got results for current database.
But tables associated with different database are not fetching.
Please guide.
You can use the sys tables sys.objects and sys.sysdepends to retrieve the information you as follows
--Replace 'YOU VIEW NAME' by the view you want
--1) using old sys tables
select distinct(ov.name),ov.xtype from sysobjects o
inner join sysdepends d on o.id=d.id
inner join sysobjects ov on d.depid=ov.id
where o.name='YOUR VIEW NAME'
--2) using new sys.table
select distinct(ov.name),ov.type from sys.objects o
inner join sys.sysdepends d on o.object_id=d.id
inner join sys.objects ov on d.depid=ov.object_id
where o.name='YOUR VIEW NAME'
Don't use information_schema (here's why) or sysdepends (here's why).
SELECT v.name,
ed.referenced_database_name,
ed.referenced_schema_name,
ed.referenced_entity_name
FROM sys.views AS v
INNER JOIN sys.sql_expression_dependencies AS ed
ON v.[object_id] = ed.referencing_id;
If you only want things in another database, add:
WHERE ed.referenced_database_name IS NOT NULL;
You have to run this query from the context of the database where the view exists.
As an aside, permissions are a little different. From the documentation:
Requires VIEW DEFINITION permission on the database and SELECT permission on sys.sql_expression_dependencies for the database.
If you don't have these permissions (explicitly, or though db_owner/sysadmin or a few other roles), you won't get an error message, the view will just return no rows.
INFORMATION_SCHEMA.VIEW_COLUMN_USAGE, on the other hand, has a little more freedom, but still has the limitation you observed (only returns references within the same database):
Returns one row for each column in the current database that is used in a view definition. This information schema view returns information about the objects to which the current user has permissions.
In order to use sys.sql_expression_dependencies, you'll need someone to grant you the appropriate permissions, or they'll need to create a stored procedure that calls it, executes as owner, and give you permissions to call that stored procedure.
I would like to have SQL user which can perform following SQL, but not able to read contents of other schemas.
What is best way to implement?
SELECT (Schema_name(A.schema_id) + '.' + A.NAME ) AS TableName,
Sum(B.rows) AS RecordCount
FROM sys.objects A
INNER JOIN sys.partitions B
ON A.object_id = B.object_id
WHERE A.type = 'U'
GROUP BY A.schema_id, A.NAME
For columns, there is a row for every permission that is different from the corresponding object-level permission. If the column permission is the same as the corresponding object permission, there is no row for it and the permission applied is that of the object.
Note: Column-level permissions override object-level permissions on
the same entity.
Specifies a permission that can be granted on a schema. Here.
In rare circumstances, combining ALTER and REFERENCE rights may allow the grantee to access data or perform prohibited operations. For instance, a user with ALTER access on a table and REFERENCE permission on a function can build and execute a calculated column over a function. The user must also have SELECT permission on the calculated column in this situation.
I am creating a security layer on few databases. As part of that I have to create a view in Original_Database that joins two tables (union) from different databases, Chained_Database1 and Chained_Database2.
USE Original_Database;
GO
CREATE VIEW QueryATable
AS
SELECT * FROM Chained_Database1.dbo.ATable
UNION
SELECT * FROM Chained_Database2.dbo.ATable;
GO
If user usergroupA (Usergroup) logs in and selects from the view QueryATable from Original_Database then he should be able to see only data from Chained_Database1.dbo.ATable.
Likewise if usergroupB logs in and selects from the view QueryATable, then he should be able to see only data from Chained_Database2.dbo.ATable.
I have tried giving different permissions to the users. It's either denying view access or giving result from two tables.
Your help is highly appreciated.
Thanks in advance!
Based on your requirements, the UNION is pointless and would only slow performance since you would select from both data sets... and then explicitly limit it to one. Theoretically you'd have a look up table for the user who ran the query, and you'd limit the results in the WHERE clause since you can't user parameters in a view. So, don't do the union. Instead create two separate views.
CREATE VIEW QueryATable
AS
SELECT * FROM Chained_Database1.dbo.ATable
GRANT SELECT ON QueryATable TO <who ever...>
GO
CREATE VIEW QueryBTable
AS
SELECT * FROM Chained_Database2.dbo.ATable
GRANT SELECT ON QueryBTable TO <who ever...>
GO
If you don't want to create separate views then you could handle this in a STORED PROCEDURE or some other way perhaps...
CREATE PROCEDURE yourProcedure(#userID)
AS
IF 1 = (SELECT COUNT(*) FROM LookUpTableA WHERE userID = #userID)
SELECT * FROM Chained_Database1.dbo.ATable
IF 1 = (SELECT COUNT(*) FROM LookUpTableB WHERE userID = #userID)
SELECT * FROM Chained_Database2.dbo.ATable
ELSE
SELECT 'User Not Valid'
GO
Note that this assumes the user would only be in one of the look up tables. If they were in both you'd need to handle it differently.
I want to know if a certain table dbo.person is being used in any of the database views in my database. There are a lot of views in this database.
I could right click each view "Script View as --> CREATE To" to see the SQL that was used to build this view but this will take a long time.
I am wondering if there is any way to query all of these "create view as" scripts to see if any of them mention my table dbo.person.
I hope this is clear.
You can query the system catalog for views (and use sql_modules to get the view definition) then use the system view sys.sql_expression_dependencies to find which of these views reference dbo.Person:
SELECT ViewName = QUOTENAME(OBJECT_SCHEMA_NAME(v.[object_id])) + '.' + QUOTENAME(v.Name),
m.[Definition]
FROM sys.views AS v
INNER JOIN sys.sql_modules AS m
ON m.[object_id] = v.[object_id]
WHERE EXISTS
( SELECT 1
FROM sys.sql_expression_dependencies AS d
WHERE d.Referenced_id = OBJECT_ID(N'dbo.Person', 'U')
AND v.[object_id] = d.referencing_id
)
ORDER BY ViewName;
There are some small issues with sys.sql_expression_dependencies, but I would still be more inclined to use this than to search for '%person%', since this could bring back 10s, or 100s of extra results, any time a table that contains person (e.g. dbo.PersonAddress) is referenced, or person is used as an alias (SELECT Forename + surname AS Person) etc. It really depends whether you are looking for something that is going to be accurate most of the time, but may, on occasion miss a reference, or whether you need a catch all solution that will bring back extra results.
You could try
select * from INFORMATION_SCHEMA.VIEWS
where VIEW_DEFINITION like '%Person%'
You might need to change the WHERE to dbo.person or [Person]
For a more detailed string search on SQL Server database object definitions please refer to SQL Object Where Used List script
You can simply call like
exec SearchInObjectsText 'name'
and it will return procedures, functions, views, etc where the text "name" is used
I know this doesn't answer the question directly, but it answers the need. I use a third party add-in called SQLSearch from redgate. It's free and I'm not an employee, so this isn't a "plug" of any kind.
I normally use this SQL to look in definitions. I didn't filter on VIEWS just in case it is used somewhere else.
SELECT
so.name, so.type, sm.Definition
FROM
sys.objects AS so INNER JOIN sys.sql_modules AS sm ON so.object_id = sm.object_id
WHERE
sm.Definition LIKE N'%dbo.person%'
ORDER BY so.name
Please query Information_Schema.View_Table system views
select * from INFORMATION_SCHEMA.VIEW_TABLE_USAGE where TABLE_NAME = 'Emp'
Try this
SELECT DISTINCT m.definition, o.name AS Object_Name,o.type_desc
FROM sys.sql_modules m
INNER JOIN sys.objects o
ON m.object_id=o.object_id
WHERE m.definition Like '%person%'
and type_desc = 'VIEW'
i am creating a table in sqlserver database using query like "SELECT Table1.* INTO Table2 FROM Table1"
here Table2 created successfully but it is not showing my database
when i again fire this query than it gives error that Table2 is already created but i can't see this in my database
i am refreshing my database also
so please help me if anyone has solution..
#Ramesh has the right idea. In some situations (I think if your user is in the db_owner role?), SELECT INTO tables are created in the schema (the SQL 2005+ terminology) associated with your login. This may be something like YOURDOMAIN\username.Table2. If you go to select again from the same login, it will work fine, but chances are that other users will not be searching in your schema.
When in doubt, explicitly create the table in the dbo schema:
SELECT Table1.*
INTO dbo.Table2
FROM Table1
have you tried with the username.Table1, like
dbo.table
Its very important to append the username for any db object, it enforces the user to select the objects which he got permission to view