Getting list of all SQL users from multiple servers - sql-server-2008

I have an task of getting the user reconciliation where we have around 50 SQL servers, I need to take the list of database users from all the SQL servers in one place and mail it to team. Any ideas will be helpful and I have SCOM server also.

I don't know any quick or fancy way, but you could do:
;with ServerPermsAndRoles as
(
select
spr.name as principal_name,
spr.type_desc as principal_type,
spm.permission_name collate SQL_Latin1_General_CP1_CI_AS as security_entity,
'permission' as security_type,
spm.state_desc
from sys.server_principals spr
inner join sys.server_permissions spm
on spr.principal_id = spm.grantee_principal_id
where spr.type in ('s', 'u')
union all
select
sp.name as principal_name,
sp.type_desc as principal_type,
spr.name as security_entity,
'role membership' as security_type,
null as state_desc
from sys.server_principals sp
inner join sys.server_role_members srm
on sp.principal_id = srm.member_principal_id
inner join sys.server_principals spr
on srm.role_principal_id = spr.principal_id
where sp.type in ('s', 'u')
)
select *
from ServerPermsAndRoles
order by principal_name
https://msdn.microsoft.com/en-us/library/ms187328.aspx
On each of the servers, and stuff the results in a single Excel spreadsheet - then using Excel, filter only unique entries.

Related

Editing the Results of a MySQL View

I'm trying to create a view in my relational MySQL database that will allow the user to update football match results from one (virtual) table within phpMyAdmin.
I have the view all setup visually how I want, and I am able to edit most of the fields, except I am getting error messages. If, for instance, I update the number of goals scored for a team, I get the following error messages shown below. It will still update that record, however, because if I refresh the page, that particular entry will change to what I entered.
I am aware that you cannot have a primary key on a view, but in terms of indexing, shouldn't the existing relationships be sufficient for this to work?
Another issue is updating the referee field. As this is a concatenated field (first_name + last_name), I cannot attempt to update it from the view.
This is my database structure:
This is the code for my view:
CREATE VIEW `view1_match_main` AS
SELECT
`match_main`.`match_id` AS `Match ID`,
`season`.`season` AS `Season`,
`match_status`.`status_no` AS `Status`,
`match_main`.`date_time` AS `Date`,
`c1`.`club_name` AS `Home Club`,
`mr1`.`goal` AS `Home Goals`,
`mr2`.`goal` AS `Away Goals`,
`c2`.`club_name` AS `Away Club`,
CONCAT(`referee`.`referee_first_name`,
' ',
`referee`.`referee_last_name`) AS `Referee`,
`stadium`.`stadium_name` AS `Stadium`,
`match_main`.`attendance` AS `Attendance`,
`match_main`.`bbc_url` AS `BBC URL`,
`match_main`.`sky_url` AS `Sky URL`
FROM
((((((((`match_main`
LEFT JOIN `referee` ON ((`match_main`.`referee_id` = `referee`.`referee_id`)))
LEFT JOIN `season` ON ((`match_main`.`season_id` = `season`.`season_id`)))
LEFT JOIN `match_status` ON ((`match_main`.`status_id` = `match_status`.`status_id`)))
LEFT JOIN `match_result` `mr1` ON (((`mr1`.`match_id` = `match_main`.`match_id`)
AND (`mr1`.`home_team` = 1))))
LEFT JOIN `club` `c1` ON ((`c1`.`club_id` = `mr1`.`club_id`)))
LEFT JOIN `match_result` `mr2` ON (((`mr2`.`match_id` = `match_main`.`match_id`)
AND (`mr2`.`home_team` = 0))))
LEFT JOIN `club` `c2` ON ((`c2`.`club_id` = `mr2`.`club_id`)))
LEFT JOIN `stadium` ON ((`c1`.`stadium_id` = `stadium`.`stadium_id`)))
ORDER BY `season`.`season` DESC , `match_main`.`date_time` , `c1`.`club_name`

MySQL Different results from same query/data

I have two servers running MySQL. Both are on windows. One, is my local machime (Windows 7, MySQL 5.6.25, 32bit) and the other is my production webserver (Windows 2012, MySQL 5.7.11-log, 64bit (that's what show variables showed me).
The data is identical between the two. I backed the data up from the windows 7 (using MySQL Workbench) and restored it on the 2012 machine.
I am running a query on both machine but I am getting different results. I have two tables, projects and projectsnotes with a 1:m relationship between them related on projects.id to projectsnotes.idProject. Each note is marked with a date (dComment). The goal of the query is to retrieve project information and the latest comment only.
Here's the query:
select space(1) as cAction,
p.id,
p.iNum,
p.cStatus,
p.cName,
p.cDesc,
ifnull(pl.cNickName, 'UNASSIGNED') as cProjectLeader,
IFNULL(concat (
date_format(pn.dComment, '%Y-%m-%d'),
': ',
pn.cComment
), '') as cComment,
date_format(p.dRequested, '%Y-%m-%d') as dRequested,
date_format(p.dRequired, '%Y-%m-%d') as dRequired,
format(p.nPercentComplete, 2) as nPercentComplete,
p.tLastUpdated,
p.bCompleted,
p.idProjectLeader
from projects p
left outer join projectleaders pl on p.idProjectLeader = pl.id
left outer join (
select idProject,
dComment,
cComment
from projectnotes
order by dComment desc,
tLastUpdated desc
) pn on p.id = pn.idProject
where p.cInstallCode = 'ITM'
and cStatus in ('Pending', 'Active', 'On Hold', 'Completed', 'Cancelled')
and bCompleted = 0
group by iNum
order by iNum;
Now, here's the weird part. When I run this on my Windows 7 machine, I get the right value for cComment. Specifically:
2017-03-28: Text from note replace
That is the latest note. When I run it on the 2012 server:
2016-05-17: Text from this note replaced too
If I run the subquery alone on the 2012 server, I get the right values (namely, a list of all the notes in the reverse order.
Oh, and this note is neither the first nor the last in the notes for this project.
So I am honestly wondering what is going on. Any thoughts on this would be greatly appreciated.
Thanks in advance.
This is expected behavior.
select ...
from projects p
left outer join projectleaders pl on p.idProjectLeader = pl.id
left outer join (...) pn on p.id = pn.idProject
where ...
group by iNum
order by iNum;
Due to MySQL's peculiar handling of GROUP BY, it will not report an error on this query. However, you must keep in mind that, since you use no aggregates, and the GROUP BY will eliminate lots of rows, the rows that are kept in the final result set are determined by rather obscure criteria...
For example:
SELECT a,b FROM t GROUP BY a
Which b will be returned? In some MySQL versions, this will be the first value of b that is found in table t. If table t is ordered in a certain way, this can be exploited. But I would definitely not trust that behavior to stay unchanged between versions... Also, remember MySQL is free to change your join order...
OK. I think I have a solution to this. Instead of doing it with a join I wrote a function that returned the value I needed as follows:
DROP FUNCTION if exists f_lastprojectnote;
DELIMITER $$
CREATE FUNCTION f_lastprojectnote(tidProject varchar(36))
RETURNS varchar(1000) DETERMINISTIC
BEGIN
DECLARE cRetVal VARCHAR(1000);
SELECT concat(date_format(pn.dComment, '%Y-%m-%d'), ': ', pn.cComment) INTO cRetVal
FROM projectnotes pn
WHERE idProject = tidProject
ORDER BY dComment DESC, tLastUpdated DESC
LIMIT 1;
RETURN cRetVal;
END$$
DELIMITER ;
It works...

Reporting Services: find all items deployed in a specific timeframe

If you put the reportmanager in listview you can see who deployed which report and when.
Can I retrieve this information somewhere and store it in a table for analysis?
I cannot seem to find how to do this, I did look through views and the internet but nothing to be found...
Any clues? Or is this not possible?
Grtz H.
You can query the ReportServer database tables to get this information.
Try something like:
select reportPath = r.Path
, report = r.Name
, created = r.CreationDate
, createdBy = c.UserName
, modified = r.ModifiedDate
, modifiedBy = m.UserName
from Catalog r -- report
inner join Users c on r.CreatedByID = c.UserID -- created
inner join Users m on r.ModifiedByID = m.UserID -- modified
where r.Type = 2 -- report catalog items only
Which returns information on all reports on the server, with created time/user and modified time/user.
You can filter by the datetime values as required.

Sql Result IN a Query

dont blame for the database design.I am not its database architect. I am the one who has to use it in current situation
I hope this will be understandable.
I have 3 tables containing following data with no foreign key relationship b/w them:
groups
groupId groupName
1 Admin
2 Editor
3 Subscriber
preveleges
groupId roles
1 1,2
2 2,3
3 1
roles
roleId roleTitle
1 add
2 edit
Query:
SELECT roles
from groups
LEFT JOIN preveleges ON (groups.groupId=preveleges.groupId)
returns specific result i.e roles.
Problem: I wanted to show roleTitle instead of roles in the above query.
I am confused how to relate table roles with this query and returns required result
I know it is feasible with coding but i want in SQL.Any suggestion will be appreciated.
SELECT g.groupName,
GROUP_CONCAT(r.roleTitle
ORDER BY FIND_IN_SET(r.roleId, p.roles))
AS RoleTitles
FROM groups AS g
LEFT JOIN preveleges AS p
ON g.groupId = p.groupId
LEFT JOIN roles AS r
ON FIND_IN_SET(r.roleId, p.roles)
GROUP BY g.groupName ;
Tested at: SQL-FIDDLE
I would change the data structure it self. Since It's not normalised, there are multiple elements in a single column.
But it is possible with SQL, if for some (valid) reason you can't change the DB.
A simple "static" solution:
SELECT REPLACE(REPLACE(roles, '1', 'add'), '2', 'edit') from groups
LEFT JOIN preveleges ON(groups.groupId=preveleges.groupId)
A more complex but still ugly solution:
CREATE FUNCTION ReplaceRoleIDWithName (#StringIds VARCHAR(50))
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE #RoleNames VARCHAR(50)
SET #RoleNames = #StringIds
SELECT #RoleNames = REPLACE(#RoleNames, CAST(RoleId AS VARCHAR(50)), roleTitle)
FROM roles
RETURN #RoleNames
END
And then use the function in the query
SELECT ReplaceRoleIDWithName(roles) from groups
LEFT JOIN preveleges ON(groups.groupId=preveleges.groupId)
It is possible without function, but this is more readable. Made without editor so it's not tested in anyway.
You also tagged the question with PostgreSQL and it's actually quite easy with Postgres to work around this broken design:
SELECT grp.groupname, r.roletitle
FROM groups grp
join (
select groupid, cast(regexp_split_to_table(roles, ',') as integer) as role_id
from privileges
) as privs on privs.groupid = grp.groupid
join roles r on r.roleid = privs.role_id;
SQLFiddle: http://sqlfiddle.com/#!12/5e87b/1
(Note that I changed the incorrectly spelled name preveleges to the correct spelling privileges)
But you should really, really re-design your data model!
Fixing your design also enables you to define foreign key constraints and validate the input. In your current model, the application would probably break (just as my query would), if someone inserted the value 'one,two,three' into the roles table.
Edit
To complete the picture, using Postgres's array handling the above could be slightly simplified using a similar approach as MySQL's find_in_set()
select grp.groupname, r.roletitle
from groups grp
join privileges privs on grp.groupid = privs.groupid
join roles r on r.roleid::text = any (string_to_array(privs.roles, ','))
In both cases if all role titles should be shown as a comma separated list, the string_agg() function could be used (which is equivalent to MySQL's group_concat()
select grp.groupname, string_agg(r.roletitle, ',')
from groups grp
join privileges privs on grp.groupid = privs.groupid
join roles r on r.roleid::text = any (string_to_array(privs.roles, ','))
group by grp.groupname

specific select work only when i add db name

I'm using SQL Server 2008 Express
All of the select statments are fine. Now I have this one:
SELECT
ORG.id, ORG.img, ORG.name, ORG.city, ORG.address,
ORG.zip, ORG.telephone, ORG.telephone2,
ORG.fax, ORG.email, ORG.vaname, ORG.vanumber,
ORG.yor_photo, ORG.commission,
Clients.id AS yor_id, Clients.prefix,
Clients.fname, Clients.lname, Clients.phone,
Clients.pelephone, Clients.email, Clients.pid,
ORG.adddate, ORG.note
FROM Org
LEFT OUTER JOIN
(select * from Clients where yor = 1) as Clients ON Clients.company = ORG.id
WHERE ORG.id=" & ORGID
It is not working, I get error "invalid object name"
If I add the DBNAME.DBO in front of the table name it works
The problem is that i don't want to change that on every project
Why is it not working?
UPDATE
the problem is not with the db name, the problem is with the AS yor_id in the select statment.
if i remove it the record retrieved is not full with all the data but if i write it the data is full but yor_id is empty
UPDATE
NEVER MIND, my bad! id column was corupted
Before that query you need to write
use DBNAME
in order to switch to your dbname.
Probably you are running that query on master database, so just do this and should work:
use DBNAME
SELECT
ORG.id, ORG.img, ORG.name, ORG.city, ORG.address,
ORG.zip, ORG.telephone, ORG.telephone2,
ORG.fax, ORG.email, ORG.vaname, ORG.vanumber,
ORG.yor_photo, ORG.commission,
Clients.id AS yor_id, Clients.prefix,
Clients.fname, Clients.lname, Clients.phone,
Clients.pelephone, Clients.email, Clients.pid,
ORG.adddate, ORG.note
FROM Org
LEFT OUTER JOIN
(select * from Clients where yor = 1) as Clients ON Clients.company = ORG.id
WHERE ORG.id=" & ORGID