Exporting database permissions to a CSV file - sql-server-2008

I am trying to export all the user information / permissions to a file for documentation. I trying to find a script out this task, is there anyway to pull all the permission from all the SQL databases from a server at one time? Working with SQL 2008 and 2012.

#Damaged I used powershell to export "Database-Level Object Permissions".. you can try below soluition.
[string]$SrvIns = 'YourServerName'
[string]$db = 'YourDatabaseName'
$sql = " SELECT
usr.name AS 'User',
CASE WHEN perm.state <> 'W' THEN perm.state_desc ELSE 'GRANT' END AS PermType,
perm.permission_name,
USER_NAME(obj.schema_id) AS SchemaName,
obj.name AS ObjectName,
CASE obj.Type
WHEN 'U' THEN 'Table'
WHEN 'V' THEN 'View'
WHEN 'P' THEN 'Stored Proc'
WHEN 'FN' THEN 'Function'
ELSE obj.Type END AS ObjectType,
CASE WHEN cl.column_id IS NULL THEN '--' ELSE cl.name END AS ColumnName,
CASE WHEN perm.state = 'W' THEN 'X' ELSE '--' END AS IsGrantOption
FROM
sys.database_permissions AS perm
INNER JOIN sys.objects AS obj
ON perm.major_id = obj.[object_id]
INNER JOIN sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
LEFT JOIN sys.columns AS cl
ON cl.column_id = perm.minor_id AND cl.[object_id] = perm.major_id
WHERE
obj.Type <> 'S'
ORDER BY
usr.name, perm.state_desc ASC, perm.permission_name ASC"
Invoke-Sqlcmd -ServerInstance $SrvIns -Database $db -Query $sql | Export-Csv C:\permission.csv
Good Luck**

Here is a script that someone found for me it works perfect. I'm posting so other people can use.
set nocount on
declare #permission table (
Database_Name sysname,
User_Role_Name sysname,
Account_Type nvarchar(60),
Action_Type nvarchar(128),
Permission nvarchar(60),
ObjectName sysname null,
Object_Type nvarchar(60)
)
declare #dbs table (dbname sysname)
declare #Next sysname
insert into #dbs
select name from sys.databases order by name
select top 1 #Next = dbname from #dbs
while (##rowcount<>0)
begin
insert into #permission
exec('use [' + #Next + ']
declare #objects table (obj_id int, obj_type char(2))
insert into #objects
select id, xtype from master.sys.sysobjects
insert into #objects
select object_id, type from sys.objects
SELECT ''' + #Next + ''', a.name as ''User or Role Name'', a.type_desc as ''Account Type'',
d.permission_name as ''Type of Permission'', d.state_desc as ''State of Permission'',
OBJECT_SCHEMA_NAME(d.major_id) + ''.'' + object_name(d.major_id) as ''Object Name'',
case e.obj_type
when ''AF'' then ''Aggregate function (CLR)''
when ''C'' then ''CHECK constraint''
when ''D'' then ''DEFAULT (constraint or stand-alone)''
when ''F'' then ''FOREIGN KEY constraint''
when ''PK'' then ''PRIMARY KEY constraint''
when ''P'' then ''SQL stored procedure''
when ''PC'' then ''Assembly (CLR) stored procedure''
when ''FN'' then ''SQL scalar function''
when ''FS'' then ''Assembly (CLR) scalar function''
when ''FT'' then ''Assembly (CLR) table-valued function''
when ''R'' then ''Rule (old-style, stand-alone)''
when ''RF'' then ''Replication-filter-procedure''
when ''S'' then ''System base table''
when ''SN'' then ''Synonym''
when ''SQ'' then ''Service queue''
when ''TA'' then ''Assembly (CLR) DML trigger''
when ''TR'' then ''SQL DML trigger''
when ''IF'' then ''SQL inline table-valued function''
when ''TF'' then ''SQL table-valued-function''
when ''U'' then ''Table (user-defined)''
when ''UQ'' then ''UNIQUE constraint''
when ''V'' then ''View''
when ''X'' then ''Extended stored procedure''
when ''IT'' then ''Internal table''
end as ''Object Type''
FROM [' + #Next + '].sys.database_principals a
left join [' + #Next + '].sys.database_permissions d on a.principal_id = d.grantee_principal_id
left join #objects e on d.major_id = e.obj_id
order by a.name, d.class_desc')
delete #dbs where dbname = #Next
select top 1 #Next = dbname from #dbs
end
set nocount off
select ##SERVERNAME as Server_name,* from #permission

Related

Convert result into doubly nested JSON format

I am trying to convert SQL Server results into a doubly nested JSON format.
Source SQL Server table:
ID
Name
Program
Type
Section
Director
Project
Sr Manager
PCM
Contractor
Cost Client
123
abc
qew
tyu
dd
ghghjg
hkhjk
fghfgf
gnhghj
gghgh
gghhg
456
yui
gdffgf
ghgf
jkjlkll
uiop
rtyuui
rfv
ujmk
rfvtg
efgg
Convert into doubly JSON as shown here:
[
[
{"key":"ID","value":"123"},
{"key":"Name","value":"abc"},
{"key":"Program","value":"qew"},
{"key":"Type","value":"tyu"},
{"key":"Section","value":"dd"},
{"key":"Director","value":"ghghjg"},
{"key":"Project","value":"hkhjk"},
{"key":"Sr Manager","value":"fghfgf"},
{"key":"PCM","value":"gnhghj"},
{"key":"Contractor","value":"gghgh"},
{"key":"Cost Client","value":"gghhg"}
],
[
{"key":"ID","value":"456"},
{"key":"Name","value":"yui"},
{"key":"Program","value":"gdffgf"},
{"key":"Type","value":"ghgfjhjhj"},
{"key":"Section","value":"jkjlkll"},
{"key":"Director","value":"uiop"},
{"key":"Project","value":"rtyuui"},
{"key":"Sr Manager","value":"rfv"},
{"key":"PCM","value":"ujmk"},
{"key":"Contractor","value":"rfvtg"},
{"key":"Cost Client","value":"efgg"}
]
]
Any help would be greatly appreciated.
Edit:
I started with this by rewriting the "FOR JSON AUTO" so that I can add "Key" "Value" text somehow.
But because my table has space in the column name, FOR XML PATH('') giving invalid XML identifier as required by FOR XML error.
that is when I thought of taking community help.
Create PROCEDURE [dbo].[GetSQLtoJSON] #TableName VARCHAR(255)
AS
BEGIN
IF OBJECT_ID(#TableName) IS NULL
BEGIN
SELECT Json = '';
RETURN
END;
DECLARE #SQL NVARCHAR(MAX) = N'SELECT * INTO ##T ' +
'FROM ' + #TableName;
EXECUTE SP_EXECUTESQL #SQL;
DECLARE #X NVARCHAR(MAX) = '[' + (SELECT * FROM ##T FOR XML PATH('')) + ']';
SELECT #X = REPLACE(#X, '<' + Name + '>',
CASE WHEN ROW_NUMBER() OVER(ORDER BY Column_ID) = 1 THEN '{'
ELSE '' END + Name + ':'),
#X = REPLACE(#X, '</' + Name + '>', ','),
#X = REPLACE(#X, ',{', '}, {'),
#X = REPLACE(#X, ',]', '}]')
FROM sys.columns
WHERE [Object_ID] = OBJECT_ID(#TableName)
ORDER BY Column_ID;
DROP TABLE ##T;
SELECT Json = #X;
END
Sample data:
CREATE TABLE [dbo].[Test1](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Col1] [int] NOT NULL,
[Col 2] varchar(50)
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Test1] ON
GO
INSERT [dbo].[Test1] ([ID], [Col1], [Col 2]) VALUES (1, 0,'ABCD')
GO
INSERT [dbo].[Test1] ([ID], [Col1] ,[Col 2]) VALUES (2, 1, 'POIU')
GO
SET IDENTITY_INSERT [dbo].[Test1] OFF
GO
You can use the following code:
Inside an APPLY, unpivot the columns as key/value pairs...
... and aggregate using FOR JSON PATH
Use STRING_AGG to do another aggregation.
SELECT '[' + STRING_AGG(CAST(v.json AS nvarchar(max)), ',') + ']'
FROM T
CROSS APPLY (
SELECT *
FROM (VALUES
('ID', CAST(ID AS nvarchar(100))),
('Name', Name),
('Program', Program),
('Type', [Type]),
('Section', Section),
('Director', Director),
('Project', Project),
('Sr Manager', [Sr Manager]),
('PCM', PCM),
('Contractor', Contractor),
('Cost Client', [Cost Client])
) v([key], value)
FOR JSON PATH
) v(json)
db<>fiddle
You cannot use FOR JSON again, because then you will get ["json": [{"key" : ...
first of all check this link you can find what you want
format-query-results-as-json-with-for-json-sql-server
but in your case you can try this
SELECT
ID,Name,Program,Type,Section,
Director,Project,Sr,Manager,PCM,Contractor,Cost,Client
FROM table
FOR JSON AUTO;
check the link there is more sample so it can help you

SQL Users, Roles and permissions Migration

Are there any scripts available to migrate SQL Server users from SQL Server 2008 to SQL Server 2008 R2 along with the User Mappings, Roles and permissions please?
I am following
https://support.microsoft.com/en-us/help/918992/how-to-transfer-logins-and-passwords-between-instances-of-sql-server
But the instructions in that link just assists in migrating the users.
The user mappings, roles and permissions don't get migrated.
Apologies if such question was already answered.
I had a quick search, but could not find a solution to my issue.
Thanks
Does this work?
/****** Object: StoredProcedure [dbo].[usp_get_object_permissions] Script Date: 10/07/2011 14:28:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- run this script from the user database
--exec usp_get_object_permissions
--drop proc usp_get_object_permissions
--go
CREATE PROCEDURE [dbo].[usp_get_object_permissions]
AS
set nocount on
set quoted_identifier off
declare #as_ObjectName sysname
set #as_ObjectName = NULL
--database owner info
select 'alter authorization on database::['+db_name()+'] to ['+ suser_sname(owner_sid)+']'
AS '--owner of database when script was created'
from master.sys.databases where name = db_name()
--drop and recreate users
select '-- It is not always necessary to drop and recreate the users it will depend on the circumstances under which you need to run this script'
select 'drop user [' + name + ']' from sys.database_principals
where principal_id > 4 and owning_principal_id is NULL
and type != 'A'
order by name
select 'CREATE USER [' + dp.name collate database_default + '] FOR LOGIN [' + sp.name + ']'+
case dp.type
when 'G' then ' '
else
' WITH DEFAULT_SCHEMA=['+dp.default_schema_name + ']'
end
as '-- by default Orphaned users will not be recreated'
from sys.server_principals sp
inner join sys.database_principals dp on dp.sid = sp.sid
where dp.principal_id > 4 and dp.owning_principal_id is NULL and sp.name <> ''
order by dp.name
-- Recreate the User defined roles
select '-- server created roles should be added by the correct processes'
select 'CREATE ROLE ['+ name + '] AUTHORIZATION ['+USER_NAME(owning_principal_id)+']'
from     sys.database_principals
    where name != 'public' and type = 'R' and is_fixed_role = 0
-- recreate application roles
select 'CREATE APPLICATION ROLE ['+ name + '] with password = '+QUOTENAME('insertpwdhere','''')+' ,default_schema = ['+default_schema_name+']'
from     sys.database_principals
    where type = 'A'
-- ADD ROLE MEMBERS
SELECT 'EXEC sp_addrolemember [' + dp.name + '], [' + USER_NAME(drm.member_principal_id) + '] ' AS [-- AddRolemembers]
FROM sys.database_role_members drm
INNER JOIN sys.database_principals dp ON dp.principal_id = drm.role_principal_id
where USER_NAME(drm.member_principal_id) != 'dbo'
order by drm.role_principal_id
-- CREATE GRANT Object PERMISSIONS SCRIPT
SELECT replace(state_desc,'_with_grant_option','') + ' '+ permission_name + ' ON ['
+ OBJECT_SCHEMA_NAME(major_id) + '].[' + OBJECT_NAME(major_id) + ']'+
case minor_id
when 0 then ' '
else
' (['+col_name(sys.database_permissions.major_Id, sys.database_permissions.minor_id) + '])'
end
+' TO [' + USER_NAME(grantee_principal_id)+']' +
case
when state_desc like '%with_grant_option' then ' with grant option'
else
' '
end
as '-- object/column permissions'
FROM sys.database_permissions (NOLOCK)
WHERE class not in (0,3) and major_id = ISNULL(OBJECT_ID(#as_ObjectName), major_id)
--AND OBJECT_SCHEMA_NAME(major_id) != 'SYS'
ORDER BY USER_NAME(grantee_principal_id),OBJECT_SCHEMA_NAME(major_id), OBJECT_NAME(major_id)
--SCHEMA permissions
SELECT replace(state_desc,'_with_grant_option','') + ' '+ permission_name + ' ON SCHEMA::['
+ SCHEMA_NAME(major_id) + ']'+
+' TO [' + USER_NAME(grantee_principal_id)+']' +
case
when state_desc like '%with_grant_option' then ' with grant option'
else
' '
end
as '-- Schema permissions'
FROM sys.database_permissions (NOLOCK)
WHERE class_desc = 'SCHEMA'
ORDER BY USER_NAME(grantee_principal_id),SCHEMA_NAME(major_id)
SELECT replace(state_desc,'_with_grant_option','') + ' '+ permission_name +
' TO [' + USER_NAME(grantee_principal_id)+']' +
case
when state_desc like '%with_grant_option' then ' with grant option'
else
' '
end
FROM sys.database_permissions (NOLOCK)
WHERE permission_name = 'VIEW DEFINITION' and class_desc = 'database'
ORDER BY USER_NAME(grantee_principal_id)

Inline SQL Not Updating

My print statement fails each time and so does my exec, anytime I try to run this statement it just tells me command completed successfully. I added the print statement to try to see what was actually being executed, but I am still mind-blown on this. Can someone here please help me?
Shouldn't the Print statement at least show me what I am trying to run? If I print each variable individually before trying to run the update it shows the correct value, so I can only assume it is something way wrong with my update statement?
Declare #fulldata varchar(30), #rsi varchar(50), #employeename varchar(50), #email varchar(50), #rsi2 varchar(50), #email2 varchar(50),
#rsiID varchar(50), #calldate datetime, #calltime datetime, #orderdate datetime, #email3 varchar(50), #uniqueID int, #sql varchar(max)
Set #fullData = 'tvdb'
Set #rsi = 'Alphabet'
Set #employeename = 'Mike Jones'
Set #email = '123abc#gmail.com'
Set #rsi2 = 'Broccoli'
Set #email2 = 'abc123#gmail.com'
Set #rsiID = 'alt16bc'
Set #calldate = '06/15/2015'
Set #calltime = '12:15:00'
Set #orderdate = '06/16/2015'
Set #email3 = 'pineapple1841#gmail.com'
Set #uniqueID = 172855
Set #sql =
'update '+#fulldata+' '
+ 'set rsi = COALESCE('''+#rsi+''',''''), '
+ 'employeename = COALESCE('''+#employeename+''',''''), '
+ 'email = COALESCE('''+#email+''',''''), '
+ 'rsi2 = COALESCE('''+#rsi2+''',''''), '
+ 'email2 = COALESCE('''+#email2+''',''''), '
+ 'rsiID = COALESCE('''+#rsiID+''',''''), '
+ 'calldate = COALESCE('''+CAST(#calldate As Varchar)+''',''''), '
+ 'calltime = COALESCE('''+CAST(#calltime As Varchar)+''',''''), '
+ 'orderdate = COALESCE('''+CAST(#orderdate As Varchar)+''',''''), '
+ 'email3 = COALESCE('''+#email3+''','''') '
+ 'where uniqueID = '+CAST(#uniqueID As Varchar)+' and '+CAST(#uniqueID As Varchar)+' > 0 '
Print #sql
exec (#sql)
EDIT ---
If I try to insert my statements into a table to check it is null. Which leads me to why is #sql not being assigned?
Insert Into #SqlStatement (sql12) VALUES (#sql)
Select * FROM #SqlStatement
Are you sure you have all lines included here? and you can run it without error?
At least your don't have declaration of #sql.
Even you declare the #sql, this line will give you error:
Set uniqueID = 172855
It should be
Set #uniqueID = 172855
Without assigning values to #uniqueID, your whole #sql is be NULL and print will generate NO output.
update tvdb set rsi = COALESCE('Alphabet',''), employeename = COALESCE('Mike Jones',''), email = COALESCE('123abc#gmail.com',''), rsi2 = COALESCE('Broccoli',''), email2 = COALESCE('abc123#gmail.com',''), rsiID = COALESCE('alt16bc',''), calldate = COALESCE('Jun 15 2015 12:00AM',''), calltime = COALESCE('Jan 1 1900 12:15PM',''), orderdate = COALESCE('Jun 16 2015 12:00AM',''), email3 = COALESCE('pineapple1841#gmail.com','') where uniqueID = 172855 and 172855 > 0
Msg 208, Level 16, State 1, Line 1
Invalid object name 'tvdb'.
To debug your code, you can comment out some lines like:
Set #sql =
'update '+#fulldata+' '
+ 'set rsi = COALESCE('''+#rsi+''',''''), '
---+ 'employeename = COALESCE('''+#employeename+''',''''), '
----+ 'email = COALESCE('''+#email+''',''''), '
----+ 'rsi2 = COALESCE('''+#rsi2+''',''''), '
----+ 'email2 = COALESCE('''+#email2+''',''''), '
----+ 'rsiID = COALESCE('''+#rsiID+''',''''), '
----+ 'calldate = COALESCE('''+CAST(#calldate As Varchar)+''',''''), '
----+ 'calltime = COALESCE('''+CAST(#calltime As Varchar)+''',''''), '
----+ 'orderdate = COALESCE('''+CAST(#orderdate As Varchar)+''',''''), '
----+ 'email3 = COALESCE('''+#email3+''','''') '
----+ 'where uniqueID = '+CAST(#uniqueID As Varchar)+' and '+CAST(#uniqueID As Varchar)+' > 0 '
Print #sql
exec (#sql)
and uncomment one line a time until you find the problematic line.
To catch values and make sure you have a non-null #sql, you need use the COALESCE this way:
Set #sql =
'update '+#fulldata+' ' ...
+ 'email = '''+COALESCE(#email,'')+''','

Format the SQL query to a variable

DECLARE #sql nvarchar(4000)
SET #sql='SELECT DISTINCT
WS.SIMNumber,
SMTP.SMTPMappingId,
CONVERT(VARCHAR(11),WS.ExpiryDate,106) as ExpiryDate,
CASE
WHEN BES.DisplayName IS NOT NULL THEN BES.DisplayName+'#'+SMTP.DomainName
ELSE
CASE WHEN BES.PIN IS NOT NULL THEN BES.PIN+'#'+SMTP.DomainName
ELSE '' END END AS EmailId,
CASE
WHEN (SELECT COUNT(*) FROM dbo.ExpiringEmailSimCardSent WHERE SimNumber=WS.SIMNumber AND ExpiryDate=WS.ExpiryDate)>0
THEN CONVERT(BIT,1)
ELSE CONVERT(BIT,0)
END AS IsEMailSent
FROM
WEBSERVICE_CACHE AS WS
LEFT OUTER JOIN
BES_SERVER_CACHE AS BES ON WS.SIMNumber = LEFT(BES.ICCID,19)
LEFT OUTER JOIN
BES_SMTP_Mapping AS SMTP ON BES.BESSqlServer = SMTP.BesServer
WHERE
CONVERT(DATETIME, GETDATE(), 109) > CONVERT(DATETIME, WS.ExpiryDate, 109)'
EXECUTE sp_executesql #sql
I have this SQL query want to convert it into a `nvarchar` variable because of # and '' . I am getting some errors
I am getting this errorMsg 102, Level 15, State 1, Line 9
Incorrect syntax near '#'.
If I rectify that it comes for another at # and ' '
You have to 'escape' your quotes:
This:
BES.PIN+'#'+SMTP.DomainName
Should be something like this:
BES.PIN+'''#'''+SMTP.DomainNam
experiment....

SQL Server : add a character in a string between 2 comma-separated values

declare #qry nvarchar(max)
set #qry='IType, INum, IDate, PO, FCode, Tx, Fr, TI, Not'
select #qry = 'select distinct ti.ID,' + #qry +
' from tblInfo ti inner join tblheadr th on ti.IA=1 AND ti.BId = ' +
CAST(#BId as varchar) + ' AND th.CUId =' + CAST(#UserID as varchar)
Now I want my query as
select distinct
ti.ID, ti.IType, ti.INum, ti.IDate, ti.PO, ti.FCode, ti.Tx, ti.Fr, ti.TI, ti.Not
from
tblInfo ti
inner join
tblheadr th on ti.IA = 1 AND ti.BId = 285 and th.CUId = 2
I need to add 'ti.' for each value in #qry..
Can you suggest me how to separate it add ti. in between #qry ?
Here's a shorter solution:
SET #qry = 'IType, INum, IDate, PO, FCode, Tx, Fr, TI, [Not]'
SET #qry = 'ti.' + REPLACE(#qry, ', ', ', ti.')
You should put Not in square brackets cause it's a reserved SQL keyword.
This should work:
select #qry =
'select distinct ti.ID,'
+ replace(replace(replace(#qry, ', Not', ', [Not]'), #qry, 'ti.' + #qry), ', ',', ti.')
+' from tblInfo ti inner join tblheadr th on ti.IA=1 AND ti.BId = '
+ QUOTENAME(CAST(#BId as varchar(max)), '''')
+ ' AND th.CUId ='
+ QUOTENAME(CAST(#UserID as varchar(max)),'''')
You really should specify size for the varchar casts, and also note that notis a keyword that needs to be escaped, so I added that. Most likely you also need to use QUOTENAME to enclose the parameter values in quotes (I added that too).
The resulting#qryvariable will be this:
select distinct
ti.ID,IType, ti.INum, ti.IDate, ti.PO, ti.FCode, ti.Tx, ti.Fr, ti.TI, ti.[Not]
from tblInfo ti
inner join tblheadr th on ti.IA=1 AND ti.BId = 'BidA' AND th.CUId ='UserA'
If the variables are declared as:
declare #userid nvarchar(max) = 'UserA'
declare #bid nvarchar(max) = 'BidA'
On a side note: looking at your join between tblInfo and tblHeadr it seems like there's no join condition, only conditions on the separate tables (that should probably be written in a WHERE clause). Maybe you forgot the join th.? = ti.? ?