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
Related
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'
I have a table say, My_Table, which does not have any indexes. I need to find under which file group it belongs to programmatically.
All the solution I searched on the internet requires an index to be present in the table.
somewhat like below..
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 i.data_space_id = 2 -- Filegroup
GO
How to know the same if the table doesn't have any indexes?
version : Microsoft SQL Server 2016 (SP1-GDR)
Could you guide me on how to view the current roles/permissions granted to any database user in Azure SQL Database or in general for a MSSQL Server instance?
I have this below query:
SELECT r.name role_principal_name, m.name AS member_principal_name
FROM sys.database_role_members rm
JOIN sys.database_principals r
ON rm.role_principal_id = r.principal_id
JOIN sys.database_principals m
ON rm.member_principal_id = m.principal_id
WHERE r.name IN ('loginmanager', 'dbmanager');
I further need to know what are the permissions granted to these roles "loginmanager" and "dbmanager"?
Could you help me on this?
Per the MSDN documentation for sys.database_permissions, this query lists all permissions explicitly granted or denied to principals in the database you're connected to:
SELECT DISTINCT pr.principal_id, pr.name, pr.type_desc,
pr.authentication_type_desc, pe.state_desc, pe.permission_name
FROM sys.database_principals AS pr
JOIN sys.database_permissions AS pe
ON pe.grantee_principal_id = pr.principal_id;
Per Managing Databases and Logins in Azure SQL Database, the loginmanager and dbmanager roles are the two server-level security roles available in Azure SQL Database. The loginmanager role has permission to create logins, and the dbmanager role has permission to create databases. You can view which users belong to these roles by using the query you have above against the master database. You can also determine the role memberships of users on each of your user databases by using the same query (minus the filter predicate) while connected to them.
To view database roles assigned to users, you can use sys.database_role_members
The following query returns the members of the database roles.
SELECT DP1.name AS DatabaseRoleName,
isnull (DP2.name, 'No members') AS DatabaseUserName
FROM sys.database_role_members AS DRM
RIGHT OUTER JOIN sys.database_principals AS DP1
ON DRM.role_principal_id = DP1.principal_id
LEFT OUTER JOIN sys.database_principals AS DP2
ON DRM.member_principal_id = DP2.principal_id
WHERE DP1.type = 'R'
ORDER BY DP1.name;
Building on #tmullaney 's answer, you can also left join in the sys.objects view to get insight when explicit permissions have been granted on objects. Make sure to use the LEFT join:
SELECT DISTINCT pr.principal_id, pr.name AS [UserName], pr.type_desc AS [User_or_Role], pr.authentication_type_desc AS [Auth_Type], pe.state_desc,
pe.permission_name, pe.class_desc, o.[name] AS 'Object'
FROM sys.database_principals AS pr
JOIN sys.database_permissions AS pe ON pe.grantee_principal_id = pr.principal_id
LEFT JOIN sys.objects AS o on (o.object_id = pe.major_id)
Further building on #brentlightsey 's answer, you can add left join to sys.schemas to also see permissions on a schema level:
SELECT DISTINCT
pr.principal_id
, pr.name AS [UserName]
, pr.type_desc AS [User_or_Role]
, pr.authentication_type_desc AS [Auth_Type]
, pe.state_desc
, pe.permission_name
, pe.class_desc
, coalesce(o.[name], sch.name) AS [Object]
FROM sys.database_principals AS pr
JOIN sys.database_permissions AS pe
ON pe.grantee_principal_id = pr.principal_id
LEFT JOIN sys.objects AS o
ON o.object_id = pe.major_id
LEFT JOIN sys.schemas AS sch
ON sch.schema_id = pe.major_id
AND class_desc = 'SCHEMA'
if you want to find about object name e.g. table name and stored procedure on which particular user has permission, use the following query:
SELECT pr.principal_id, pr.name, pr.type_desc,
pr.authentication_type_desc, pe.state_desc, pe.permission_name, OBJECT_NAME(major_id) objectName
FROM sys.database_principals AS pr
JOIN sys.database_permissions AS pe ON pe.grantee_principal_id = pr.principal_id
--INNER JOIN sys.schemas AS s ON s.principal_id = sys.database_role_members.role_principal_id
where pr.name in ('youruser1','youruser2')
I wanted to list all the table names, column names , schema names and owner in all databases and wrote the code below . I am not sure where to get the schema owners details to add to my query . Please help .
select c.name as colomn_name , t.name as table_name , s.name as schema_name
from sys.columns c
inner join sys.tables t on c.object_id=t.object_id
INNER JOIN sys.schemas AS s ON t.[schema_id] = s.[schema_id]
The column principal_id in sys.schemas contains the ID of the schema owner, so to get the name you can simply use:
USER_NAME(s.principal_id) AS Schema_Owner
Alternatively, if you want more information you can join to sys.sysusers:
SELECT s.Name, u.*
FROM sys.schemas s
INNER JOIN sys.sysusers u
ON u.uid = s.principal_id
Here is a more portable solution that works under SQL Server:
SELECT schema_name, schema_owner
FROM information_schema.schemata
in Sql Server 2005, I have a master table, and several other tables which are related to
this master through several one to many relations.
How can I find all tables and fields which are in relation with the
primary key in the master table, on "many" side?
I know I can extract this by querying views from INFORMATION_SCHEMA,
but I don't know where exactly I can find this info.
Thank you
Check out:
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE
I found the answer with some help on sql server groups
I use the following query, which returns me schema name, table and field name on one and many side of the relations:
SELECT
SchemaParent.name AS ParentSchemaName,
TableParent.name AS ParentTableName,
ColumnParent.name AS ParentColumnName,
SchemaChild.name AS ChildSchemaName,
TableChild.name AS ChildTableName,
ColumnChild.name AS ChildColumnName
FROM
sys.foreign_key_columns AS kc INNER JOIN
sys.objects AS TableChild ON kc.parent_object_id = TableChild.object_id INNER JOIN
sys.schemas AS SchemaChild ON TableChild.schema_id = SchemaChild.schema_id INNER JOIN
sys.objects AS TableParent ON kc.referenced_object_id = TableParent.object_id INNER JOIN
sys.schemas AS SchemaParent ON TableParent.schema_id = SchemaParent.schema_id INNER JOIN
sys.columns AS ColumnParent ON kc.referenced_object_id = ColumnParent.object_id AND kc.referenced_column_id = ColumnParent.column_id INNER JOIN
sys.columns AS ColumnChild ON kc.parent_object_id = ColumnChild.object_id AND kc.parent_column_id = ColumnChild.column_id
ORDER BY ParentTableName, ChildTableName