How to get all synonyms of a specific schema - sql-server

I am using SQL Server 2019 and create in schema load synonyms based on a linked server. I have searched on the internet to a way to fetch a list of the created synonyms and find this URL ( https://anyonconsulting.com/business_intelligence/how-to-get-a-list-of-all-the-synonyms-in-sql-server-instance/ )
and execute the below statement:
SELECT name AS synonym_name,
base_object_name AS synonym_definition,
COALESCE (PARSENAME (base_object_name, 4), ##servername) AS server_name,
COALESCE (PARSENAME (base_object_name, 3), DB_NAME (DB_ID ())) AS DB_name,
COALESCE (PARSENAME (base_object_name, 2), SCHEMA_NAME (SCHEMA_ID ())) AS schema_name,
PARSENAME (base_object_name, 1) AS table_name,
create_date,
modify_date
FROM sys.synonyms
After executing this statement I get an empty result. So my question is how to get a list of the created synonyms based on linked server(s)
Solution
Thanks to the latest reply I fix the problem to put the database and schema name after the from:
SELECT name AS synonym_name,
base_object_name AS synonym_definition,
COALESCE (PARSENAME (base_object_name, 4), ##servername) AS server_name,
COALESCE (PARSENAME (base_object_name, 3), DB_NAME (DB_ID ())) AS DB_name,
COALESCE (PARSENAME (base_object_name, 2), SCHEMA_NAME (SCHEMA_ID ())) AS schema_name,
PARSENAME (base_object_name, 1) AS table_name,
create_date,
modify_date
FROM DEV_100_Load.sys.synonyms
Many thanks

SELECT name AS synonym_name,
base_object_name AS synonym_definition,
COALESCE (PARSENAME (base_object_name, 4), ##servername) AS server_name,
COALESCE (PARSENAME (base_object_name, 3), DB_NAME (DB_ID ())) AS DB_name,
COALESCE (PARSENAME (base_object_name, 2), SCHEMA_NAME (SCHEMA_ID ())) AS schema_name,
PARSENAME (base_object_name, 1) AS table_name,
create_date,
modify_date
FROM DEV_100_Load.sys.synonyms

Related

Convert PostgreSQL query to SQL Server query

I need to convert my query
select
unnest(string_to_array(names, ',')) as "Admin Name",
unnest(string_to_array(phones, ',')) as "Admin Phone",
unnest(string_to_array(emails, ',')) as "Admin Emails"
from
metadata_Table
to an equivalent SQL Server query.
Any suggestions?
You cannot exactly this easily in SL Server. There is no "string_split() with ordinality". And, the ordering is not guaranteed with string_split().
Until Microsoft enhances this functions, my suggestion is a recursive subquery:
with cte as (
select convert(varchar(max), null) as name, convert(varchar(max), null) as phone, convert(varchar(max), null) as email,
convert(varchar(max), names + ',') as names_rest,
convert(varchar(max), phones + ',') as phones_rest,
convert(varchar(max), emails + ',') as emails_rest,
0 as lev
from metadata_Table
union all
select left(names_rest, charindex(',', names_rest) - 1),
left(phones_rest, charindex(',', phones_rest) - 1),
left(emails_rest, charindex(',', emails_rest) - 1),
stuff(names_rest, 1, charindex(',', names_rest), ''),
stuff(phones_rest, 1, charindex(',', phones_rest), ''),
stuff(emails_rest, 1, charindex(',', emails_rest), ''),
lev + 1
from cte
where emails_rest like '%,%'
)
select *
from cte
where lev > 0;

Transact SQL (mssql) Return name of DB from SELECT "search"

Running Microsoft SQL Server 11.0.3128
on Windows Server 2012 R2 Essentials
I am attempting to return the name of a specific database based on a supplied variable (batch file that calls SQL script).
The process, in my head, should look something like this:
For each database in instance
Look in the current database
Return databasename if variable is found in column
The code I've been working with so far looks like this:
EXEC dbo.sp_MSForeachdb '
USE [?];
SELECT DB_NAME() AS DBName
UNION SELECT
ColumnName
FROM dbo.Items
WHERE ColumnName =''variable''
'
Problem is, this returns a lot more than I want it to since it returns "null" values for the databases that do not contain "variable" and creates messages for databases not containing "ColumnName".
But I can't seem to figure out how to get the specific info I want without the other stuff. First time poster, please let me know if I can improve the question.
Thanks!
EDIT: Oops, didn't realize at first you were working with mssql and not mysql. The principle below will still work; you'll just need to adjust the syntax a bit and use a user-function to replace group_concat since mssql doesn't have that.
Here's an approach without sp_MSForeachdb. Note that you will want to sanitize the parameters first.
delimiter $$
create procedure FindDatabases
(
in varName varchar(2000),
in tableName varchar(2000),
in columnName varchar(2000)
)
begin
declare selectQuery varchar(2000);
select group_concat(
concat('select ''',
table_schema,
''' as DatabaseName from ',
table_schema,
'.',
tableName,
' where ',
columnName,
' = ''',
varName,
'''')
separator ' union ') as DatabaseNames
from information_schema.tables
where table_name = tableName
into #selectQuery;
prepare preparedSql from #selectQuery;
execute preparedSql;
deallocate prepare preparedSql;
end $$
delimiter ;
Example usage:
call FindDatabases ( 'variable', 'Items', 'ColumnName' )
This procedure generates a sql query for each database with a table name matching the table name supplied, unions them together, and then executes them. Each query in the union returns its database name if the specified table in that database has a column matching the specified name that contains a value that matches the specified variable name. Only databases matching these requirements will be present in the query results, so you don't have to worry about null values in the results.
ADDITIONAL EDIT: As promised, here is a sqlserver version.
create procedure FindDatabases
(
#varName varchar(2000),
#tableName varchar(2000),
#columnName varchar(2000)
)
as
begin
declare #selectQuery nvarchar(2000)
-- first, get a list of database names that contain the specified table
IF OBJECT_ID('tempdb.dbo.#db_temp') IS NOT NULL
DROP TABLE #db_temp
CREATE TABLE #db_temp (DatabaseName SYSNAME)
SELECT #selectQuery = (
SELECT '
USE [' + d.name + '];
INSERT INTO #db_temp (DatabaseName)
SELECT DB_NAME() as DatabaseName
WHERE EXISTS(
SELECT 1
FROM sys.objects
WHERE [object_id] = OBJECT_ID(''' + #tableName + ''')
AND [type] = ''U''
)'
FROM sys.databases d
WHERE d.name NOT IN ('master', 'tempdb', 'model', 'msdb')
AND d.state_desc != 'OFFLINE'
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
EXEC sys.sp_executesql #selectQuery
-- use something like mysql's group_concat function to turn that list into a bunch of union all select statements
select
#selectQuery =
(
SELECT LEFT(database_names , LEN(database_names ) - 10) AS database_names
FROM #db_temp AS extern
CROSS APPLY
(
SELECT 'select ''' + DatabaseName + ''' as DatabaseName from ' + DatabaseName + '.dbo.' + #tableName +
' where ' + #columnName + ' = ''' + #varName + '''' + ' union all '
FROM #db_temp AS intern
FOR XML PATH('')
) pre_trimmed (database_names)
GROUP BY database_names
)
drop table #db_temp
-- run those select statements
exec sp_executesql #selectQuery
end
To run it:
exec FindDatabases 'someVar', 'Items', 'ColumnName'
I shamelessly pulled some snippets from here and here to work around the lack of a group_concat function and sqlserver's information_schema having only the local database's info and not sharing information across databases.

Union 50+ tables with different number of columns using SQL Server

I have over 50 different tables which I would like to combine into one big table. All the tables have a different number of columns.
Currently, to union the tables together, I am writing an individual select statement for each of the tables, and inserting a null column if that column doesn't exist in the table. Then I am using UNION ALL to union them together.
For example:
(
select col1
, null as col2
, col3
from table1
union all
select col1
, col2
, null as col
from table2
)
Although this works, it is very manual and time consuming. Is there a better, more efficient way to union these tables into one? As with over 50 tables, I am going to have thousands of lines of code.
Thank you!
You can query SQL Server metadata, and from the result dynamically construct a SQL statement. This can be done in any programming language, including T-SQL itself.
Here's a rough example; execute this query, copy/paste the result back into the query window, and execute that.
If the 50 tables have similar names (e.g. all start with Foo), then you can replace the exhaustive table list (WHERE TABLE_NAME IN ('table1', 'table2', 'table3') in my example) by WHERE TABLE_NAME LIKE 'Foo%'.
WITH
AllTables (TABLE_NAME) AS (
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME IN ('table1', 'table2', 'table3')
),
TablesWithSelectors (TABLE_NAME, COLUMN_NAME, Selector) AS (
SELECT t.TABLE_NAME, a.COLUMN_NAME, CASE WHEN b.COLUMN_NAME IS NULL THEN 'NULL AS ' ELSE '' END + a.COLUMN_NAME
FROM AllTables t
CROSS JOIN (SELECT DISTINCT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME IN (SELECT TABLE_NAME FROM AllTables)) a
LEFT OUTER JOIN INFORMATION_SCHEMA.COLUMNS b ON b.TABLE_NAME = t.TABLE_NAME AND b.COLUMN_NAME = a.COLUMN_NAME
),
SelectStatements (Sql) AS (
SELECT
'SELECT ' +
STUFF((
SELECT ', ' + Selector
FROM TablesWithSelectors
WHERE TABLE_NAME = r.TABLE_NAME
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
, 1, 2, '') +
' FROM ' +
TABLE_NAME
FROM TablesWithSelectors r
GROUP BY TABLE_NAME
)
SELECT STUFF((
SELECT ' UNION ALL ' + sql
FROM SelectStatements
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)'), 1, 11, '')
Thanks to:
How to use GROUP BY to concatenate strings in SQL Server?

How to select rows having empty values in all columns of the table in SQL Server?

I do not want put all the columns like:
select *
from tbl_AllTransactiondata
where column1='' and column2=''
Please help for short way because there are around 16 columns.
I need to get all the rows having empty data in all columns in SQL Server.
Interesting question. I just learned something. You can use CHECKSUM(). Try this:
CREATE TABLE #tmp (
col1 varchar(31)
,col2 varchar(31)
);
INSERT INTO #tmp (col1,col2) VALUES ('','');
SELECT COUNT(*)
FROM #tmp
WHERE CHECKSUM(*)=CHECKSUM('');
DROP TABLE #tmp;
This returns a result of 1.
So, if you do a SELECT from your table WHERE CHECKSUM(*)=CHECKSUM('') it will return all the rows where all columns are empty strings.
One possible solution is using dynamic query, if you want to not hard-code the field names
DECLARE #sqlStr VARCHAR(max) = (
SELECT stuff((
SELECT 'and ' + c.NAME + ' is null '
FROM sys.columns c
WHERE object_name(object_id) = 'yourtablename'
ORDER BY c.NAME
FOR XML PATH('')
), 1, 3, '')
)
SET #sqlStr = 'select * from ' + yourtablename + ' where ' + #sqlStr
PRINT #sqlStr
EXEC (#sqlStr)
Please "Mark as Answer" if a post has answered the question
I tried below query and it works fine
SELECT *
FROM tbl_AllTransactiondata
WHERE COALESCE(column1, column2, column3, column4, column5, column6, column7,
column8, column9, column10, column11, column12, column13,
column14, column15, column16) =''

Get number of tables in each database in SQL Server

SELECT d.NAME
,ROUND(SUM(mf.size) * 8 / 1024, 0) Size_MBs
,(SUM(mf.size) * 8 / 1024) / 1024 AS Size_GBs
FROM sys.master_files mf
INNER JOIN sys.databases d ON d.database_id = mf.database_id
WHERE d.database_id > 4
GROUP BY d.NAME
ORDER BY d.NAME
I have the above T-SQL script which lists all databases on an SQL Server instance along with their corresponding size in MBs & GBs.
What i'm struggling with is also to include a column for the number of tables in each database.
Does any one also know how i can improve the above script to also show the total numbers of tables in each listed database. Optionally, it would be nice to get also the number of rows in each table but this is not a big issue.
I'm targeting sql server 2005 and obove.
Not as a single script, you could obtain the requested result by
CREATE TABLE AllTables ([DB Name] sysname, [Schema Name] sysname, [Table Name] sysname)
DECLARE #SQL NVARCHAR(MAX)
SELECT #SQL = COALESCE(#SQL,'') + '
insert into AllTables
select ' + QUOTENAME(name,'''') + ' as [DB Name], [Table_Schema] as
[Table Schema], [Table_Name] as [Table Name] from ' +
QUOTENAME(Name) + '.INFORMATION_SCHEMA.Tables;' FROM sys.databases
ORDER BY name
EXECUTE(#SQL)
SELECT * FROM AllTables ORDER BY [DB Name],[SCHEMA NAME], [Table Name]
DROP TABLE AllTables
Reference:List of All Tables in All Databases
A wider report about all your databases could include stats over tables, views, procedures, triggers, amenities (xml, spatial indexes) and so far.
if object_ID('TempDB..#AllTables','U') IS NOT NULL drop table #AllTables
CREATE TABLE #AllTables (
[DB Name] sysname,
[Tables] int,
[Views] int,
[Procedures] int,
[Triggers] int,
[Full Text Catalogs] int,
[Xml Indexes] int,
[Spatial Indexes] int)
DECLARE #SQL NVARCHAR(MAX)
SELECT #SQL = COALESCE(#SQL,'') + 'USE ' + quotename(name) + '
insert into #AllTables
select ' + QUOTENAME(name,'''') + ' as [DB Name],
(select count(*) from ' + QUOTENAME(Name) + '.sys.tables),
(select count(*) from ' + QUOTENAME(Name) + '.sys.views),
(select count(*) from ' + QUOTENAME(Name) + '.sys.procedures),
(select count(*) from ' + QUOTENAME(Name) + '.sys.triggers),
(select count(*) from ' + QUOTENAME(Name) + '.sys.fulltext_catalogs),
(select count(*) from ' + QUOTENAME(Name) + '.sys.xml_indexes),
(select count(*) from ' + QUOTENAME(Name) + '.sys.spatial_indexes)
'
FROM sys.databases
ORDER BY name
-- print #SQL -- debug
EXECUTE(#SQL)
SELECT * FROM #AllTables
The provided solution, being far to be optimal, is easy to master and extend.
NOT OPTIMAL, just for sporadic report
based on (and credits to): http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/how-to-get-information-about-all-databas/

Resources