How to list all database objects with no dependencies? - sql-server

I would like to list all database objects in a Microsoft SQL database that have no dependencies - e.g. there are no other database objects that depend on them.
I could find this for each table in SQL Server Management Studio, but this is very time consuming (right click on a table, "Check Dependencies"):
(example of a table with no dependencies)
I'm looking how to do this programatically for all database objects in a database - in T-SQL.

You can use the following script to get all objects with no dependendcies.
SELECT
schema_name = s.name,
o.name,
FROM sys.objects o
JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE NOT EXISTS (SELECT 1
FROM sys.objects o2
WHERE o2.parent_object_id = o.object_id
)
AND NOT EXISTS (SELECT 1
FROM sys.sql_expression_dependencies sed
WHERE sed.referenced_id = o.object_id
);
Note that the first NOT EXISTS will exclude all objects with keys, indexes or defaults. If you only want to look at procedures, functions and views, then remove that.
SELECT
schema_name = s.name,
o.name,
FROM sys.objects o
JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE NOT EXISTS (SELECT 1
FROM sys.sql_expression_dependencies sed
WHERE sed.referenced_id = o.object_id
);
Note also that dependency checking is not perfect. In particular, dynamic SQL obviously doesn't work, and it won't check application code.
But it's also not reliable for cases when the schema is not specified in the reference.

Charlieface, thanks again for your answer!
I just needed this again and I revisited your answer. I have a small update to your solution / query.
The query returns system tables too, which is something one probably doesn't want to have in the results list.
Updated query:
SELECT
schema_name = s.name,
o.name,
o.type_desc
FROM
sys.objects o
INNER JOIN
sys.schemas s ON s.schema_id = o.schema_id
WHERE
NOT EXISTS (SELECT 1 FROM sys.objects o2 WHERE o2.parent_object_id = o.object_id)
AND NOT EXISTS (SELECT 1 FROM sys.sql_expression_dependencies sed WHERE sed.referenced_id = o.object_id)
AND o.type_desc<>'SYSTEM_TABLE'

Related

SQL Server database roles - tables

I try to to find a SQL statement to get an overview of all database roles to table connections. So I am searching for an n:m connection between sys.tables and sys.database_principals where type_desc='DATABASE_ROLE'.
The goal is to have an overview which roles are on which tables. Can anyone help?
I am using Microsoft SQL Server 2019.
Kind regards
sys.database_permissions is what you are looking for. You can join that to sys.tables and sys.database_principals and get all the info you need
SELECT
schema_name = s.name,
t.name,
per.permission_name,
prin.name,
prin.state_desc
FROM sys.tables t
JOIN sys.schemas s ON s.schema_id = t.schema_id
JOIN sys.database_permissions ON per.major_id = t.object_id
AND per.class = 1 -- object or column
AND per.minor_id = 0 -- table only, not column
JOIN sys.database_principals prin ON prin.principal_id = per.grantee_principal_id
AND prin.type = 'R'; -- same as DATABASE_ROLE

How to enumerate all the objects belonging to a file group using SQL query?

How to enumerate all the objects belonging to a file group using SQL query?
I can look up the SSMS > Object Explorer > Properties > Storage on the each table and other objects to see what file group they belong to, but it might not be a feasible solution with hundreds of objects in the database.
From http://blog.sqlauthority.com/2009/06/01/sql-server-list-all-objects-created-on-all-filegroups-in-database/
SELECT o.[name], o.[type], i.[name], i.[index_id], f.[name] FROM sys.indexes i
INNER JOIN sys.filegroups f
ON i.data_space_id = f.data_space_id
INNER JOIN sys.all_objects o
ON i.[object_id] = o.[object_id] WHERE i.data_space_id = f.data_space_id
AND o.type = 'U' -- User Created Tables
You can alter the o.type to control what object types get returned.

How to check if user has permissions to see View definitions on SQL Server?

How to find if the logged in User has permissions to see "view" definitions on SQL Server? I need to find out what tables/columns a view is made from,
I used this SQL for the same; for view definition, we used this query:
Query:
select *
from sys.objects
where name like '%SECTION_MASTER_V%'
Result: 579337674
Query:
SELECT definition
FROM sys.objects o
JOIN sys.sql_modules m ON m.object_id = o.object_id
WHERE o.object_id = 579337674
AND o.type = 'V'
Result: null
I get null as a result. Does anyone knows what may be wrong here?
You can see object-level permissions using this query: the commented-out section in the WHERE clause will limit the results to the VIEW DEFINITION permission.
SELECT
o.name AS ObjectName,
su.name AS LoginName,
dp.permission_name AS PermissionType,
dp.state_desc AS PermissionStatus
FROM
sys.database_permissions dp
INNER JOIN
sys.objects o ON
dp.major_id = o.object_id
INNER JOIN
sys.sysusers su ON
dp.grantee_principal_id = su.uid
--WHERE dp.[type] = 'vw'
ORDER BY o.name
Two things:
Use sp_helptext: it's a lot easier than jumping through system tables.
You can use sys.fn_my_permissions to see what permissions you have on any object.

list of tables without indexes in sql 2008

How do I list tables without indexes in my SQL 2008 database?
Edit
I want the Schema name and the Table name.
This should cover what your looking for. i.e. tables that are heaps (no clustered index) and do not have any non-clustered indexes. It uses the new sys. table objects used in 2005/2008.
in addition, you probably want to look for tables that do have a clustered index, but have no nonclustered indexes (this is the 2nd part of the statement which I've left commented out.
SELECT
schemaname = OBJECT_SCHEMA_NAME(o.object_id)
,tablename = o.NAME
FROM sys.objects o
INNER JOIN sys.indexes i ON i.OBJECT_ID = o.OBJECT_ID
-- tables that are heaps without any nonclustered indexes
WHERE (
o.type = 'U'
AND o.OBJECT_ID NOT IN (
SELECT OBJECT_ID
FROM sys.indexes
WHERE index_id > 0
)
)
-- OR
-- table that have a clustered index without any nonclustered indexes
--(o.type='U'
-- AND o.OBJECT_ID NOT IN (
-- SELECT OBJECT_ID
-- FROM sys.indexes
-- WHERE index_id>1))
Here's an example:
select SCHEMA_NAME(schema_id), name from sys.tables
where OBJECTPROPERTY(object_id, 'IsIndexed')= 0
In addition to #Philip Fourie's suggestion you might want to think about which indexes to create.
Once you have been accessing your data, SQL Server 2008 keeps track of places where it thinks indexes will be helpful (it refers to these as "missing indexes." There are a hand full of new Dynamic Managed Views which can show these missing indexes and some info about them.
From MSSQlTips:
sys.dm_db_missing_index_details - Returns detailed information about a missing index
sys.dm_db_missing_index_group_stats - Returns summary information about missing index groups
sys.dm_db_missing_index_groups - Returns information about a specific group of missing indexes
sys.dm_db_missing_index_columns(index_handle) - Returns information about the database table columns that are missing for an index. This is a function and requires the index_handle to be passed.
select shema = s.name, table_name = o.name
from sys.objects o
join sys.schemas s on o.schema_id = s.schema_id
where type = 'U'
and not exists (select i.index_id
from sys.indexes i
where i.type <> 0 --ignore default heap index row
and o.object_id = i.object_id )
Edit:
I have updated the SQL to include the Schema name as requested. (Note I had to sys.objects instead of sysobjects to cater for schemas that were introduced in SQL 2005)
The catalog tables are documented in the SQL Server documentation, see this link.
This FAQ contains more samples and might also be useful.
Note that these are system tables and can change between SQL server versions, where possible rather use the system table-independent views called Information Schema Views.
This code gives all the details about the indexes for all the tables:
SELECT
sch.name AS [Schema],
obj.name AS TableName,
indx.name AS IndexName,
CASE
WHEN indx.type_desc = 'HEAP' THEN 'N/A'
ELSE indx.type_desc
END AS IndexType
FROM sys.objects obj
JOIN sys.indexes indx ON indx.object_id = obj.object_id
JOIN sys.schemas AS sch ON sch.schema_id = obj.schema_id
WHERE
obj.type = 'U'
ORDER BY
obj.name

How do I query schema bound views?

I can list all views in SQL Server 2008 by using
SELECT * FROM sys.views
What I want to do is to list only the views that are schema bound. How can I do this?
SELECT *
FROM sys.views
WHERE OBJECTPROPERTY(object_id, 'IsSchemaBound') = 1
I needed to find the schema bound views for a specific table. This worked for me in SQL Server 2019.
select distinct
o.type, SCHEMA_NAME(o.schema_id), o.name
--, *
from sys.sql_dependencies d
inner join sys.objects o
on d.object_id = o.object_id
where d.class = 1 -- OBJECT_OR_COLUMN_REFERENCE_SCHEMA_BOUND
and d.referenced_major_id = OBJECT_ID(N'dbo.MyTable')
order by 1, 2, 3
;

Resources