Dynamic SQL query to list all master table's data - sql

I have N numbers of Master tables in my database. To see all the data in the master tables, currently I'm writing SELECT query for each table. So I like to write a sql query to list all my master table's data in my database.
Since we are using a same standard for all master tables, so all the master tables are ending with the suffix Master only. Like RoleMaster, UserMaster, UserRoleMaster, OfficeMaster, PincodeMaster and many.
What I have tried:
The below query, returns the SELECT query for all master table.
SELECT 'SELECT * FROM ' + name FROM sysobjects WHERE xtype = 'U' AND name LIKE '%Master'
It returns
SELECT * FROM RoleMaster
SELECT * FROM UserMaster
SELECT * FROM UserRoleMaster
SELECT * FROM OfficeMaster
SELECT * FROM PincodeMaster
...
...
Executing the below query always returns one table's data only. The PRINT statement returns SELECT * FROM RoleMaster only.
DECLARE #DynamicSql AS VARCHAR (MAX) = '';
SELECT #DynamicSql = 'SELECT * FROM ' + name FROM sysobjects WHERE xtype = 'U' AND name LIKE '%Master'
PRINT #DynamicSql
EXEC (#DynamicSql)
What is the issue, what I missed here, why its not list all master table's data.

You need to add the #DynamicSql variable before start of the dynamic query, like SELECT #DynamicSql = #DynamicSql + '
After QUOTENAME(T.name) you need to add a delimiter + '; ' to split the each line.
So the below query will works in your case:
DECLARE #DynamicSql AS NVARCHAR (MAX) = '';
SELECT #DynamicSql = #DynamicSql +
'SELECT * FROM ' + QUOTENAME(S.name) + '.' + QUOTENAME(T.name) + '; '
FROM sys.objects T
JOIN sys.schemas S ON S.schema_id = T.schema_id
WHERE T.[type] = 'U' AND T.name LIKE '%Master'
--PRINT #DynamicSql
EXEC (#DynamicSql)
Edit: Based on this comment, I have updated the answer.

Related

No of records in each table [duplicate]

This question already has answers here:
Query to list number of records in each table in a database
(23 answers)
Closed 5 years ago.
How to get a list of all tables with no of records in a particular database in SQL Server.
Thanks
Here's another option - not dependent on INFORMATION_SCHEMA.
This would also allow you to alter your where clause (you may edit your #QUERY accordingly).
DECLARE #QUERY VARCHAR(MAX)
SET #QUERY = ''
/*
* Create a long query with a row count + table name.
* You may alter your where clause here
*/
SELECT #QUERY =
#QUERY + ' SELECT COUNT(*), ''' + QUOTENAME(name)
+ ''' FROM ' + QUOTENAME(name) + CHAR(13)
+ 'UNION ALL'
FROM sys.tables
--Get rid of the last 'UNION ALL'...
SELECT #QUERY = LEFT(#QUERY, LEN(#QUERY) - 10)
--Prepare a temp table - drop if exists and then create it
IF object_id('tempdb..#TableResults') IS NOT NULL
DROP TABLE #TableResults
CREATE TABLE #TableResults(
Count INT,
TableName VARCHAR(MAX)
);
--Insert the main query result into the temp table
INSERT INTO #TableResults
EXEC(#QUERY);
--Select all from the temp table
SELECT * FROM #TableResults
WHERE COUNT = 0
You will need to use Dynamic SQL and check for existance of rows in each table
declare #sql nvarchar(max)
select #sql = isnull(#sql + ' union all ' + char(13) , convert(nvarchar(max), ''))
+ 'select tbl_name = ''' + name + ''' '
+ 'where not exists (select * from ' + quotename(name) + ')'
from sys.tables
print #sql
exec (#sql)
Did you mean this
SELECT COUNT(*) FROM
INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME IN
(
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE')
Saravanan

How to print table columns to use in an INSERT query

I need to run some SQL which will return my columns from a table.
I need to use these columns in an INSERT statement.
I could run:
select *
from information_schema.columns
where table_name = 'tableName'
but I need to print something like this:
[table.custid], [table.address], [table.name]
I thought you may need them to use for example with dynamic sql, you can get the list of column in the format you want as:
DECLARE #ColNames VARCHAR(1000)
SELECT #ColNames = COALESCE(#ColNames+', ', '') + QUOTENAME('tableName.'+NAME,'[')
FROM SYS.COLUMNS
WHERE OBJECT_id = OBJECT_id('tableName')
SELECT #ColNames
Edit summary: adding tablename prefix to columns as wanted in question
Try this
SELECT * FROM SYS.COLUMNS
WHERE object_id = OBJECT_ID('dbo.TableName')
DECLARE #sql as VARCHAR(8000)
SET #sql = ' '
SELECT #sql += '[table.'+[Name] + '],' FROM SYS.COLUMNS
WHERE object_id = OBJECT_ID('dbo.TableName')
PRINT(#sql)

How to query a table with wildcard in the name

I have a bunch of tables, that have the same first few characters in the names, but the tables have random numbers (equal in length) at the end of the names.
They have the same structure.
I want to union them into one table, dynamically.
This is in SQL Server 2008 Express.
I have no real idea how to do this, but I'm guessing I have to loop thru a list of the tables names, maybe using a list in the system tables?
Example (that illustrates my simple minded thinking, as I'm sure this make no real technical sense)
SELECT * FROM TABLE0*
UNION ALL
SELECT * FROM TABLE0*
Note '*' is a a number with 8 digits.
A quick dynamic SQL script should do it:
declare #sql varchar(max)
set #sql = ''
select #sql = #sql + case len(#sql) when 0 then '' else ' UNION ALL ' end + '
SELECT * FROM [' + table_name + ']'
from
information_schema.tables where table_name like 'TABLE0%'
exec (#sql)
You could use a simple query like this to construct your large query:
SELECT 'SELECT * FROM '+name+ ' UNION '
FROM sys.tables
WHERE name LIKE '%yourtable%'
Or you could use dynamic SQL to build it and run it:
DECLARE #sql VARCHAR(MAX)
SET #sql = ''
SELECT #sql = #sql +'
UNION ALL
SELECT * FROM ['+name+']'
FROM sys.tables
WHERE name LIKE '%yourtable%'
SET #sql = STUFF(#sql,1,15,'')
EXEC(#sql)

how do I select records that are like some string for any column in a table?

I know that I can search for a term in one column in a table in t-sql by using like %termToFind%. And I know I can get all columns in a table with this:
SELECT *
FROM MyDataBaseName.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'MyTableName`
How can I perform a like comprparison on each of the columns of a table? I have a very large table so I can't just spell out LIKE for each column.
As always, I'll suggest xml for this (I'd suggest JSON if SQL Server had native support for it :) ). You can try to use this query, though it could perform not so well on large number of rows:
;with cte as (
select
*,
(select t.* for xml raw('data'), type) as data
from test as t
)
select *
from cte
where data.exist('data/#*[local-name() != "id" and contains(., sql:variable("#search"))]') = 1
see sql fiddle demo for more detailed example.
Important note by Alexander Fedorenko in comments: it should be understood that contains function is case-sensitive and uses xQuery default Unicode code point collation for the string comparison.
More general way would be to use dynamic SQL solution:
declare #search nvarchar(max)
declare #stmt nvarchar(max)
select #stmt = isnull(#stmt + ' or ', '') + quotename(name) + ' like #search'
from sys.columns as c
where c.[object_id] = object_id('dbo.test')
--
-- also possible
--
-- select #stmt = isnull(#stmt + ' or ', '') + quotename(column_name) + ' like #search'
-- from INFORMATION_SCHEMA.COLUMNS
-- where TABLE_NAME = 'test'
select #stmt = 'select * from test where ' + #stmt
exec sp_executesql
#stmt = #stmt,
#params = N'#search nvarchar(max)',
#search = #search
sql fiddle demo
I'd use dynamic SQL here.
Full credit - this answer was initially posted by another user, and deleted. I think it's a good answer so I'm re-adding it.
DECLARE #sql NVARCHAR(MAX);
DECLARE #table NVARCHAR(50);
DECLARE #term NVARCHAR(50);
SET #term = '%term to find%';
SET #table = 'TableName';
SET #sql = 'SELECT * FROM ' + #table + ' WHERE '
SELECT #sql = #sql + COALESCE('CAST('+ column_name
+ ' as NVARCHAR(MAX)) like N''' + #term + ''' OR ', '')
FROM INFORMATION_SCHEMA.COLUMNS WHERE [TABLE_NAME] = #table
SET #sql = #sql + ' 1 = 0'
SELECT #sql
EXEC sp_executesql #sql
The XML answer is cleaner (I prefer dynamic SQL only when necessary) but the benefit of this is that it will utilize any index you have on your table, and there is no overhead in constructing the XML CTE for querying.
In case someone is looking for PostgreSQL solution:
SELECT * FROM table_name WHERE position('your_value' IN (table_name.*)::text)>0
will select all records that have 'your_value' in any column. Didn't try this with any other database.
Unfortunately this works as combining all columns to a text string and then searches for a value in that string, so I don't know a way to make it match "whole cell" only. It will always match if any part of any cell matches 'your_value'.

Need to Query Tables that are dynamically created

We have an application that stores logged data in a Database called "ACManager" and Table called "Events_1".
When this table gets to a certain number of records the software creates another table called "Events_2". This continues as the data grows. I need to be able to query this data automatically as if it's all in one table without interference. Using a UNION will eventually create invalid querys when a new table is created dynamically by the application. Please also take into account performance.
So we need to Query as one table without UNION:
Select *
FROM ACManager.Events_1 , ACManager.Events_2 , ACManager.Events_xxxx(as needed)
Use dynamic sql. try this
DECLARE #query VARCHAR(MAX)
SET #query='Select *
FROM SELECT STUFF((SELECT '','' + name
from sys.tables where name like ''Events%''
FOR XML PATH('''')), 1, 1, '''') '
EXEC #query
In this script you create procedure. In body of the procedure uses dynamic sql which build sql statement and then run this statement
CREATE PROCEDURE dbo.getEvents
AS
DECLARE #dml nvarchar(max)
SELECT #dml = COALESCE(#dml + ' UNION ALL SELECT * FROM ', 'SELECT * FROM ')
+ QUOTENAME(s.name) + '.' + QUOTENAME(t.name)
FROM sys.schemas s INNER JOIN sys.tables t ON s.schema_id = t.schema_id
WHERE s.name = 'dbo' AND t.name LIKE 'event%'
--PRINT #dml
EXEC sp_executesql #dml
See demo on SQLFiddle