Set table name in a SELECT statement from a nested select - sql

I have a table in MSSQL which has been called tables_list, it has a list of tables.
How can I use this list in another SELECT to count number of rows in each table and reach a list like the following picture:
SELECT T.[TABLE_NAME], count(*) AS NUMBERS
FROM [db_name].[schema_name].[T.[TABLE_NAME]]
(SELECT [TABLE_NAME],
FROM [db_name].[schema_name].[tables_list]) T

in sql server you can use system partition table to get the row counts in a database :
SELECT * FROM
(SELECT
QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + '.' + QUOTENAME(sOBJ.name) AS [TableName],
SUM(sPTN.Rows) AS [RowCount]
FROM
sys.objects AS sOBJ
INNER JOIN sys.partitions AS sPTN ON sOBJ.object_id = sPTN.object_id
WHERE
sOBJ.type = 'U'
AND sOBJ.is_ms_shipped = 0x0
AND index_id < 2 -- 0:Heap, 1:Clustered
GROUP BY
sOBJ.schema_id,
sOBJ.name
ORDER BY [TableName]) X
WHERE X.[TableName] IN
(SELECT
CONCAT('[schema_name].[prefix', [TABLE_NAME], ']')
FROM [db_name].[schema_name].[tables_list])

Related

Combining the Result of Two Select SQL Queries involving Joins

I need to combine these two SQL queries to find the total count of empty & non empty tables in a given schema.
The below query produces two result outputs - which is correct.
But how I can join two of these select statements together as one single query statement with two result outputs?
I have tried using Union, Union all, Intersect all, and it will not give me the results I am looking for.
--- query for Empty tables:
select count (*) from
(
select schema_name(tab.schema_id) + '.' + tab.name as [emptytable]
from sys.tables tab
inner join sys.partitions part
on tab.object_id = part.object_id
where part.index_id IN (1, 0) -- 0 - table without PK, 1 table with PK
group by schema_name(tab.schema_id) + '.' + tab.name
having sum(part.rows) = 0
) as subquery;
--- query for Non-Empty tables:
select count (*) from
(
select schema_name(tab.schema_id) + '.' + tab.name as [non_emptyTable]
from sys.tables tab
inner join sys.partitions part
on tab.object_id = part.object_id
where part.index_id IN (1, 0) -- 0 - table without PK, 1 table with PK
group by schema_name(tab.schema_id) + '.' + tab.name
having sum(part.rows) > 0
) as subquery;
Use conditional aggregation:
select sum(case when size = 0 then 1 else 0 end) as num_empty,
sum(case when size > 0 then 1 else 0 end) as num_nonempty
from (select schema_name(tab.schema_id) + '.' + tab.name as table_name,
sum(part.rows) as size
from sys.tables tab join
sys.partitions part
on tab.object_id = part.object_id
where part.index_id in (1, 0) -- 0 - table without PK, 1 table with PK
group by schema_name(tab.schema_id) + '.' + tab.name
) t

List the tables used by the sql script, and the nature of access to the table

I have a script with thousand of lines and I want to extract all the tables (& temp tables) the script references, and also the nature of access to the table such as select, insert, update or delete. Is there a tool we can use for this purpose?
Sample script (input):
SELECT * FROM Table1
UPDATE Table1 SET Col1 = 1
DELETE FROM Table2
EXEC 'INSERT INTO #Table3 SELECT ''Test'''
Sample output:
1. Table1 - select, update
2. Table2 - delete
3. #Table3 - insert
You may find the following query useful, however, one thing it doesn't give you is the references from dynamic SQL statements (and perhaps also table variables and temp tables).
I think to get the level of information you're looking for you'd probably need to write your own script/program. Previously I wrote something that gave me the results from the below query, including any dynamic SQL references, in C# using SQL Server Management Objects (SMO).
SELECT DISTINCT
OBJECT_SCHEMA_NAME(D.referencing_id) referencing_object_schema
, OBJECT_NAME(D.referencing_id) referencing_object_name
, O.[type_desc] referencing_object_type
, D.referenced_schema_name
, D.referenced_entity_name
, D.referenced_id
,
CASE
WHEN O_REF.[object_id] IS NOT NULL THEN O_REF.[type_desc]
WHEN T.user_type_id IS NOT NULL THEN 'USER_DEFINED_TYPE'
END referenced_object_type
FROM
sys.sql_expression_dependencies D
LEFT JOIN sys.objects O ON D.referencing_id = O.[object_id]
LEFT JOIN sys.objects O_REF ON D.referenced_id = O_REF.[object_id]
LEFT JOIN sys.types T ON D.referenced_id = T.user_type_id
There is a system function called: fn_dblog. You could use it as below:
IF OBJECT_ID('tempdb..#tempLog') IS NOT NULL DROP TABLE #tempLog
-- Raw Data
SELECT DISTINCT
[AllocUnitName],
Operation
INTO #tempLog
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation IN ('LOP_INSERT_ROWS','LOP_MODIFY_ROW',
'LOP_DELETE_ROWS','LOP_BEGIN_XACT','LOP_COMMIT_XACT')
AND [AllocUnitName] is not null
ORDER By [AllocUnitName], Operation
-- SELECT * FROM #tempLog
-- Display Enhancement and Grouping
SELECT [AllocUnitName], Operations = STUFF((
SELECT N', ' + REPLACE(operation,'LOP_', '')
FROM #tempLog
WHERE [AllocUnitName] = x.[AllocUnitName]
FOR XML PATH(''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 2, N'')
FROM #tempLog AS x
WHERE [AllocUnitName] is not null
GROUP BY [AllocUnitName]
ORDER BY [AllocUnitName]

T-SQL Query to get table dependencies for all tables in database

I have the start of a query below which gives me dependencies of a particular table:
SELECT DISTINCT OBJECT_NAME(object_id) AS referencing_object_name
FROM sys.sql_dependencies
WHERE referenced_major_id = OBJECT_ID('TABLE_NAME_HERE')
But is there a way to alter this to show:
1) The above with a column with tablename being populated
2) The above relating to ALL tables within a set database (not just a single table as the original query shows)
3) All results on a single row
Final output looking like image below:
screenshotoffinalquery
.
.
.
EDIT:
I seem to be very close with this, but last column is duplicating a single result
SELECT DISTINCT b.name, a.referenced_major_id, b.object_id,
substring((
SELECT ' || ' +OBJECT_NAME(a.object_id)
FROM sys.sql_dependencies a JOIN sys.tables b ON a.referenced_major_id = b.object_id
For XML PATH ('')
), 2, 1000) AS [TextLine]
FROM sys.sql_dependencies a JOIN sys.tables b ON a.referenced_major_id = b.object_id
ORDER BY b.name ASC

How to Retrieve Column Headers of a Select Query?

How it is possible to retrieve column headers of a select query as a single column in SQL Server ? (it is preferred to retrieve data type of columns )
Query example:
select a.PartId, a.PartName, b.GroupName
from Parts as a
inner join Groups as b on a.GroupRef = b.GroupId
Expected result:
Columns
--------
PartId
PartName
GroupName
Starting from SQL Server 2012+ you can use sys.dm_exec_describe_first_result_set to get all metadata about result set:
DBFiddle Demo
DECLARE #tsql NVARCHAR(MAX) =
N'select a.PartId , a.PartName , b.GroupName
from Parts as a inner join Groups as b
on a.GroupRef = b.GroupId';
SELECT name AS [Columns]
FROM sys.dm_exec_describe_first_result_set(#tsql, NULL, 1)
One way is to create a temporary table with the schema of resultset and then query tempdb's schema table to get the column names and details. You can get all needed details.
select a.PartId , a.PartName , b.GroupName into #yourtable
from Parts as a inner join Groups as b
on a.GroupRef = b.GroupId
where 1=2
SELECT c.name as columnname,t.name as datatype
FROM tempdb.sys.columns c
inner join tempdb.sys.systypes as t on t.xtype = c.system_type_id
WHERE [object_id] = OBJECT_ID(N'tempdb..#yourtable');
SELECT 'PartId', 'PartName', 'GroupName'
UNION ALL
select a.PartId , a.PartName , b.GroupName
from Parts as a inner join Groups as b
on a.GroupRef = b.GroupId

Append Table Name to Field Name with Select *

Sorry if this is a duplicate. I have searched but only find aliasing fields and tables.
I have a query:
SELECT *
FROM MyTable1 ca LEFT OUTER JOIN MyTable2 dcn ON dcn.dstrct_code = ca.dstrct_code
LEFT OUTER JOIN MyTable2 cdn ON cdn.dstrct_code = ca.cost_dstrct_cde
LEFT OUTER JOIN MyTable3 bb ON bb.supplier_code = ca.supplier_code
WHERE ca.dstrct_code = '0001'
AND ca.req_232_type = 'P'
AND ca.requisition_no = '264982 000'
AND ca.alloc_count = '01'
ORDER BY ca.alloc_count ASC
Please dont shoot me down for using * im not done with the query yet. If I execute this query I get a row of data however the tables I am selecting from all have a good number of fields and many are simularly named. So my question is... Is there anyway to select * from and append the table name to the field name so it is more obvious which field belongs to which table?
I don't think there's a way to do that directly but you can do this instead. Run a query like this:
SELECT
(case t.name when 'MyTable1' then 'ca' when 'MyTable2' then 'dcn' when 'MyTable3' then 'cdn' when 'MyTable4' then 'bb' end)
+ '.' + c.name
+ ' AS "' + t.name + '.' + c.name + '",'
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE t.name in ('MyTable1', 'MyTable2', 'MyTable3', 'MyTable4')
ORDER BY t.name
Run it, preferably with results to Text (Ctrl+T), and use the results instead of the * in your original query. You have to manually remove the comma from the last line.
If you like the approach, you could streamline the process with some dynamic SQL.