using sys.columns from a different databases and servers - sql-server

Solution specified here, works as follows (I run from server1)
select * from server1.blahdbname.sys.columns c
where c.[object_id] = OBJECT_ID('blahdbname.dbo.blahtablename')
It is fine. Works as intended. But below query doesn't work (changed servername) (returns empty set)
select * from server2.blahdbname.sys.columns c
where c.[object_id] = OBJECT_ID('blahdbname.dbo.blahtablename')
What is the universal way if I want to query different servers too? Above queries generated dynamically, so I want them to work on any server and db
NOTE: blahdbname and blahtablename both exist in server1 and server2. server1 and server2 are linked

This is because you are using the function OBJECT_ID. This runs against the current database, not the remote database.
Instead you should use the system views on the remote server to make this happen.
select c.*
from server1.blahdbname.sys.columns c
join server1.blahdbname.sys.tables t on c.object_id = c.object_id
where t.name = 'blahtablename'

Related

How to find biggest files in cluster

Postgres 13 cluster in Debian Linux server contains 30 databases. Databases contain number of schemas.
How to find biggest files which occupy most space in disk ?
I tried
select
relname::char(25),
pg_size_pretty(pg_total_relation_size(c.oid))::char(10) as totalsize,
n.nspname::char(12),
case
when c.relkind='i' then 'index'
when c.relkind='t' then 'toast'
when c.relkind='r' then 'table'
when c.relkind='v' then 'view'
when c.relkind='c' then 'composite type'
when c.relkind='S' then 'sequence'
else c.relkind::text
end ::char(14) as "type"
from
pg_class c
left join pg_namespace n on n.oid = c.relnamespace
left join pg_tablespace t on t.oid = c.reltablespace
where
(pg_total_relation_size(c.oid)>>21)>0 order by
pg_total_relation_size(c.oid) desc
But it returns sizes for current database only. How to run in over whole cluster ? Can some plpgsql script used for this.
Output should include database name column.
Client application uses psqlODBC to get data so psql or shell scripts should preferably avoided.
You cannot do that, as you can only query the database to which you are connected. You need to connect to each database in turn.

Query System Views From Linked Server - SQL Server

I'm tasked with creating a report that will pull down the permissions from different servers and display them.
I'm having an issue with the query not picking up all of the rows in from the system view, from another server.
When I run the below query on serverA, it gives me 251 results.
SELECT COUNT(*) FROM ServerA.employee.sys.objects
When I run the same code from ServerB, I get 153 results.
I compared the two and it looks like the linked server isn't pulling type_desc of SQL_SCALAR_FUNCTION, SQL_STORED_PROCEDURE, and SYSTEM_TABLE.
Does anyone know way I can get a list of database object permissions running from a different server in SQL server?
If you are using SSRS for the report, you can setup a dynamic data source to run the same report for multiple servers/databases. I'd use a static data source at first to setup the datasets, otherwise the columns will not get created automatically.
="Data Source=" & Parameters!ServerName.Value & ";Initial Catalog=" & Parameters!DatabaseName.Value
Here is the listing of permissions on schema objects within a database.
SELECT
pr.principal_id
, pr.name
, pr.type_desc
, pr.authentication_type_desc
, pe.state_desc
, pe.permission_name
, ObjectName = s.name + '.' + o.name
FROM
sys.database_principals AS pr
INNER JOIN sys.database_permissions AS pe ON pe.grantee_principal_id = pr.principal_id
INNER JOIN sys.objects AS o ON pe.major_id = o.object_id
INNER JOIN sys.schemas AS s ON o.schema_id = s.schema_id;
Microsoft Reference

SQL Statement with OR never finishes executing, freezes SQL Database

I have an SQL statement
SELECT dbo.sem_computer.COMPUTER_NAME,dbo.sem_computer.COMPUTER_ID,
[IP_ADDR1_TEXT],dbo.sem_computer.COMPUTER_DOMAIN_NAME, [ID],dbo.SEM_AGENT.AGENT_VERSION
FROM sem_computer, [dbo].[V_SEM_COMPUTER], IDENTITY_MAP, SEM_CLIENT,dbo.SEM_AGENT
WHERE [dbo].[V_SEM_COMPUTER].COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID and dbo.IDENTITY_MAP.ID = dbo.SEM_CLIENT.GROUP_ID
and dbo.SEM_COMPUTER.COMPUTER_ID = dbo.SEM_CLIENT.COMPUTER_ID
AND dbo.SEM_COMPUTER.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID
AND NAME = 'My Company\Default Group'
OR NAME = 'My Company\Bronx'
order by [IP_ADDR1_TEXT]
That executed indefinitely and even freezes the SQL server when I tried to copy and paste this code.
If I remove the
OR NAME = 'My Company\Bronx'
then the the SQL statement executes just fine
We are using SQL Server 2008
Thank you
I think this whole problem becomes a lot clearer if you write ANSI-Compliant T-SQL. So rather than have your able join conditions in the WHERE clause, you have something like:
SELECT
dbo.sem_computer.COMPUTER_NAME
, dbo.sem_computer.COMPUTER_ID
, [IP_ADDR1_TEXT]
, dbo.sem_computer.COMPUTER_DOMAIN_NAME
, [ID]
, dbo.SEM_AGENT.AGENT_VERSION
FROM
sem_computer AS COM
INNER JOIN
[dbo].[V_SEM_COMPUTER] AS V
ON
COM.COMPUTER_ID = V.COMPUTER_ID
INNER JOIN
dbo.SEM_CLIENT AS CLI
ON
COM.COMPUTER_ID = CLI.COMPUTER_ID
INNER JOIN
dbo.SEM_AGENT AS AGT
ON
COM.COMPUTER_ID = AGT.COMPUTER_ID
INNER JOIN
IDENTITY_MAP AS IM
ON
CLI.GROUP_ID = IM.ID
...
Then your WHERE clause does what it is designed to do, which is filter your data. This becomes, as suggested earlier
WHERE
NAME IN('My Company\Default Group','My Company\Bronx')
The performance problem you had was, as pointed out, you were getting a cross join of all tables. But I think you would have noticed this if you write your joins in an ANSI compliant way.
I hope that helps.
Ash
OR NAME IN('My Company\Default Group','My Company\Bronx')
Should work.
When you have the AND NAME = 'My Company\Default Group'
OR NAME = 'My Company\Bronx' not in parentheses or using an IN clause, it means that it will get everything where the OR condition is satisfied, ignoring all of the other conditions.

HowTo Generate List of SQL Server Jobs and their owners

How would I go about generating a list of sql jobs and their owners? I would also like to be able to generate this list for SSIS packages also.
Thanks
try this
Jobs
select s.name,l.name
from msdb..sysjobs s
left join master.sys.syslogins l on s.owner_sid = l.sid
Packages
select s.name,l.name
from msdb..sysssispackages s
left join master.sys.syslogins l on s.ownersid = l.sid
It's better to use SUSER_SNAME() since when there is no corresponding login on the server the join to syslogins will not match
SELECT s.name ,
SUSER_SNAME(s.owner_sid) AS owner
FROM msdb..sysjobs s
ORDER BY name
A colleague told me about this stored procedure...
USE msdb
EXEC dbo.sp_help_job
If you don't have access to sysjobs table (someone elses server etc) you might be have or be allowed access to sysjobs_view
SELECT *
from msdb..sysjobs_view s
left join master.sys.syslogins l on s.owner_sid = l.sid
or
SELECT *, SUSER_SNAME(s.owner_sid) AS owner
from msdb..sysjobs_view s
There is an easy way to get Jobs' Owners info from multiple instances by PowerShell:
Run the script in your PowerShell ISE:
Loads SQL Powerhell SMO and commands:
Import-Module SQLPS -disablenamechecking
BUild list of Servers manually (this builds an array list):
$SQLServers = "SERVERNAME\INSTANCE01","SERVERNAME\INSTANCE02","SERVERNAME\INSTANCE03";
$SysAdmins = $null;
foreach($SQLSvr in $SQLServers)
{
## - Add Code block:
$MySQL = new-object Microsoft.SqlServer.Management.Smo.Server $SQLSvr;
DIR SQLSERVER:\SQL\$SQLSvr\JobServer\Jobs| FT $SQLSvr, NAME, OWNERLOGINNAME -Auto
## - End of Code block
}

Compare structures of two databases?

I wanted to ask whether it is possible to compare the complete database structure of two huge databases.
We have two databases, the one is a development database, the other a production database.
I've sometimes forgotten to make changes in to the production database, before we released some parts of our code, which results that the production database doesn't have the same structure, so if we release something we got some errors.
Is there a way to compare the two, or synchronize?
For MySQL database you can compare view and tables (column name and column type) using this query:
SET #firstDatabaseName = '[first database name]';
SET #secondDatabaseName = '[second database name]';
SELECT * FROM
(SELECT
CONCAT(cl.TABLE_NAME, ' [', cl.COLUMN_NAME, ', ', cl.COLUMN_TYPE, ']') tableRowType
FROM information_schema.columns cl, information_schema.TABLES ss
WHERE
cl.TABLE_NAME = ss.TABLE_NAME AND
cl.TABLE_SCHEMA = #firstDatabaseName AND
ss.TABLE_TYPE IN('BASE TABLE', 'VIEW')
ORDER BY
cl.table_name ) AS t1
LEFT JOIN
(SELECT
CONCAT(cl.TABLE_NAME, ' [', cl.COLUMN_NAME, ', ', cl.COLUMN_TYPE, ']') tableRowType
FROM information_schema.columns cl, information_schema.TABLES ss
WHERE
cl.TABLE_NAME = ss.TABLE_NAME AND
cl.TABLE_SCHEMA = #secondDatabaseName AND
ss.TABLE_TYPE IN('BASE TABLE', 'VIEW')
ORDER BY
cl.table_name ) AS t2 ON t1.tableRowType = t2.tableRowType
WHERE
t2.tableRowType IS NULL
UNION
SELECT * FROM
(SELECT
CONCAT(cl.TABLE_NAME, ' [', cl.COLUMN_NAME, ', ', cl.COLUMN_TYPE, ']') tableRowType
FROM information_schema.columns cl, information_schema.TABLES ss
WHERE
cl.TABLE_NAME = ss.TABLE_NAME AND
cl.TABLE_SCHEMA = #firstDatabaseName AND
ss.TABLE_TYPE IN('BASE TABLE', 'VIEW')
ORDER BY
cl.table_name ) AS t1
RIGHT JOIN
(SELECT
CONCAT(cl.TABLE_NAME, ' [', cl.COLUMN_NAME, ', ', cl.COLUMN_TYPE, ']') tableRowType
FROM information_schema.columns cl, information_schema.TABLES ss
WHERE
cl.TABLE_NAME = ss.TABLE_NAME AND
cl.TABLE_SCHEMA = #secondDatabaseName AND
ss.TABLE_TYPE IN('BASE TABLE', 'VIEW')
ORDER BY
cl.table_name ) AS t2 ON t1.tableRowType = t2.tableRowType
WHERE
t1.tableRowType IS NULL;
If you prefer using tool with UI you can also use this script
https://github.com/dlevsha/compalex
which can compare tables, views, keys etc.
Compalex is a lightweight script to compare two database schemas. It
supports MySQL, MS SQL Server and PostgreSQL.
Screenshot (compare tables)
You can use the command line:
mysqldump --skip-comments --skip-extended-insert -d --no-data -u root -p dbName1>file1.sql
mysqldump --skip-comments --skip-extended-insert -d --no-data -u root -p dbName2>file2.sql
diff file1.sql file2.sql
You can just dump them with --no-data and compare the files.
Remember to use the --lock-tables=0 option on your production database to avoid the big nasty global lock.
If you use the same mysqldump version (your dev and production systems should have the same software, right?) then you'll expect to get more-or-less identical files out. The tables will be in alpha order so a simple diff will show discrepancies up easily.
To answer this kind of question currently, I've made a script that uses information_schema content to compare column, datatype, and table
SET #database_current = '<production>';
SET #database_dev = '<development>';
-- column and datatype comparison
SELECT a.TABLE_NAME, a.COLUMN_NAME, a.DATA_TYPE, a.CHARACTER_MAXIMUM_LENGTH,
b.COLUMN_NAME, b.DATA_TYPE, b.CHARACTER_MAXIMUM_LENGTH
FROM information_schema.COLUMNS a
LEFT JOIN information_schema.COLUMNS b ON b.COLUMN_NAME = a.COLUMN_NAME
AND b.TABLE_NAME = a.TABLE_NAME
AND b.TABLE_SCHEMA = #database_current
WHERE a.TABLE_SCHEMA = #database_dev
AND (
b.COLUMN_NAME IS NULL
OR b.COLUMN_NAME != a.COLUMN_NAME
OR b.DATA_TYPE != a.DATA_TYPE
OR b.CHARACTER_MAXIMUM_LENGTH != a.CHARACTER_MAXIMUM_LENGTH
);
-- table comparison
SELECT a.TABLE_SCHEMA, a.TABLE_NAME, b.TABLE_NAME
FROM information_schema.TABLES a
LEFT JOIN information_schema.TABLES b ON b.TABLE_NAME = a.TABLE_NAME
AND b.TABLE_SCHEMA = #database_current
WHERE a.TABLE_SCHEMA = #database_dev
AND (
b.TABLE_NAME IS NULL
OR b.TABLE_NAME != a.TABLE_NAME
);
Hope this script can also help people that looks for a non-application solution, but the usage of script. Cheers
I tried mysqldiff without success, so I would like to enrich the future readers by drawing attention to mysqlworkbench's compare function. http://dev.mysql.com/doc/workbench/en/wb-database-diff-report.html#c13030
if you open a model tab, and select the databases menu, you get a compare schemas option, which you can use to compare two different schemas on two different servers, or two schemas on the same server, or a schema and a model, or a lot of other options i haven't tried yet.
For mysql on Linux, it is possible via phpmyadmin to export the databases without 'data' and only structure.
Scrolling through the export options for the entire database, just deselect 'data' and set the output to text. Export both databases you wish to compare.
Then in file compare in your preferred program / site, compare the two text file outputs of the databases. Synchronization is still manual in this solution, but this is effective for comparing and finding the structural differences.
Depending on your database, the tools available vary.
I use Embarcadero's ER/Studio for this. It has a Compare and Merge feature.
There are plenty others, such as Toad for MySQL, that also have compare. Also agree on the Red-Gate suggestion, but never used it for MySQL.
Check out Gemini Delta - SQL Difference Manager for .NET. A free beta version is available for download, but the full version is only a few days away from public release.
It doesn't compare row-level data differences, but it compares tables, functions, sprocs, etc... and it is lightning fast. (The new version, 1.4, loads and compares 1k Sprocs in under 4 seconds, compared with other tools I've tested which took over 10 seconds.)
Everyone is right though, RedGate does make great tools.

Resources