Sample SQL Data - sql

I want to present a schema to my BA team.
Select TABLE_NAME, col.DATA_TYPE
from INFORMATION_SCHEMA.COLUMNS col
order by col.TABLE_CATALOG, TABLE_NAME, TABLE_SCHEMA, col.ORDINAL_POSITION
I want to present 3 rows of sample data as well but I wanted to pivot it out so they get an output that has the following 3 columns:
Table_Name
Data_Type
Sample_Data
How do I pivot that data?

Here is a solution based on cursors and dynamic SQL. I've includes the table schema and column names in the final result as well, though the question just asks fro table name, data type, and sample data.
Also, I wasn't sure if you wanted three rows of sample data per table/column, or if you wanted one row per table/column with three columns of sample data. I went with the former, please let me know if you wanted the later. I did include a "No data" indicator for tables that don't have any sample data.
Tested on SQL Server 2005, but I think it should work with 2000 as well.
Create Table #results
(id Integer Not Null Identity(1, 1)
,table_schema nVarChar(128) Not Null
,table_name nVarChar(128) Not Null
,column_name nVarChar(128) Not Null
,data_type nVarChar(128) Not Null
,sample_data nVarChar(max) Null);
Declare #table_name nVarChar(128)
,#table_schema nVarChar(128)
,#column_name nVarChar(128)
,#data_type nVarChar(128)
,#sql nVarChar(max)
,#inserted Integer;
Declare rs Cursor Local Forward_Only Static Read_Only
For Select
col.table_schema
,col.table_name
,col.column_name
,col.data_type
From INFORMATION_SCHEMA.COLUMNS col
Order By col.TABLE_CATALOG
,col.TABLE_SCHEMA
,col.TABLE_NAME
,col.ORDINAL_POSITION
Open rs;
Fetch Next From rs Into #table_schema, #table_name, #column_name, #data_Type;
While ##Fetch_Status = 0 Begin;
Set #table_schema = QuoteName(#table_schema);
Set #table_name = QuoteName(#table_name);
Set #column_name = QuoteName(#column_name);
Set #sql = N'
Insert Into #results
(table_schema
,table_name
,column_name
,data_type
,sample_data)
Select Top 3 ' + QuoteName(#table_schema, '''') + N'
,' + QuoteName(#table_name, '''') + N'
,' + QuoteName(#column_name, '''') + N'
,' + QuoteName(#data_type, '''') + N'
,' + #column_name + N'
From ' + #table_schema + N'.' + #table_name;
Exec (#sql);
Select #inserted = count(*)
From #results
Where table_schema = #table_schema
And table_name = #table_name
And column_name = #column_name;
If #inserted = 0
Insert Into #results (table_schema, table_name, column_name, data_type, sample_data)
Values (#table_schema, #table_name, #column_name, #data_type, ' -- No Data -- ');
Fetch Next From rs Into #table_schema, #table_name, #column_name, #data_Type;
End;
Close rs;
Deallocate rs;
-- Probably should include the schema and column name too:
Select table_schema, table_name, column_name, data_type, sample_data
From #results
Order by [id];
-- But this is what the question asked for:
-- Select table_name, data_type, sample_data
-- From #results
-- Order by [id];
Drop Table #results;
There are probably more elegant solutions available, but this should get you started, I think. Good luck!

I built this using XML PATH
SET NOCOUNT ON
SELECT
'SELECT ''' + col.TABLE_NAME + ''' AS TableName,' +
'''' + col.COLUMN_NAME + ''' AS ColumnName,'+
' ''' + col.DATA_TYPE + ''' as DataType, ' +
'
(
SELECT top 3 CONVERT (VARCHAR, p2.' + col.COLUMN_NAME + ') + '',''
FROM ' + col.TABLE_SCHEMA + '.' + col.TABLE_NAME + ' p2
ORDER BY p2. ' + col.COLUMN_NAME + '
FOR XML PATH('''')
)
UNION ALL'
FROM INFORMATION_SCHEMA.COLUMNS col
ORDER BY
col.TABLE_CATALOG,
col.TABLE_NAME,
col.TABLE_SCHEMA,
col.ORDINAL_POSITION
I copy paste the result of this query into a new query editor window. I delete the last UNION ALL and execute the query.
It gives me an additional comma in the Returned data, but my B.A.'s were OK with that.

You can dynamically build queries like this for each table:
SELECT TOP 3 *
FROM mytable
FOR XML AUTO
and parse the resulting XML in the presenation layer.

Related

Dynamic SQL to get rows from information_schema

Let’s say I’m looking for a specific column in my database so I have something like this
SELECT COLUMN_NAME, TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME like ‘%employeeid%’
But I also want to know how many rows each table has, I was told I can do this using Dynamic SQL so I have this now
DECLARE
#tableName NVARCHAR(MAX),
#sql NVARCHAR(MAX),
#colName NVARCHAR(MAX);
DECLARE CUR_TABLE CURSOR FOR
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS
OPEN CUR_TABLE
FETCH NEXT FROM CUR_TABLE
INTO #tableName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #colName = '%employeeid%'
SET #sql = 'SELECT COLUMN_NAME, TABLE_NAME, (SELECT COUNT(*) FROM ' + #tableName +') AS ROWS FROM INFORMATION_SCHEMA.COLUMNS where column_name like ' + ''' + #colName + ''';
FETCH NEXT FROM CUR_TABLE
INTO #tableName
END;
CLOSE CUR_TABLE
DEALLOCATE CUR_TABLE
EXEC sp_executesql #sql
But this doesn't work, What I'm trying to do is query a table with the column I am looking for, with the table name, and number of rows in the table.
How can I fix this?
You can make use of SQL Server's dynamic management views to quickly obtain the row counts*.
Find all tables with a column named 'MyColumn' and their current rows:
select Schema_Name(t.schema_id) schemaName, t.name TableName, s.row_count
from sys.columns c
join sys.tables t on t.object_id = c.object_id
join sys.dm_db_partition_stats s on s.object_id = c.object_id and s.index_id <= 1
where c.name='MyColumn';
* Accurate except for frequently updated tables where there could be some lag
The following uses INFORMATION_SCHEMA, dynamic SQL, and STRING_AGG() to build a query that will return a single result set.
DECLARE #ColumnName sysname = 'ProductID'
DECLARE #Newline VARCHAR(2) = CHAR(13) + CHAR(10)
DECLARE #SqlTemplate NVARCHAR(MAX) =
+ 'SELECT'
+ ' ColumnName = <ColumnNameString>,'
+ ' TableName = <TableSchemaAndNameString>,'
+ ' Rows = (SELECT COUNT(*) FROM <TableSchemaAndName>)'
+ #Newline
DECLARE #UnionSql NVARCHAR(100) = 'UNION ALL ' + #Newline
DECLARE #Sql NVARCHAR(MAX) = (
SELECT STRING_AGG(
REPLACE(REPLACE(REPLACE(
#SqlTemplate
, '<ColumnNameString>', QUOTENAME(C.COLUMN_NAME, ''''))
, '<TableSchemaAndNameString>', QUOTENAME(C.TABLE_SCHEMA + '.' + C.TABLE_NAME, ''''))
, '<TableSchemaAndName>', QUOTENAME(C.TABLE_SCHEMA) + '.' + QUOTENAME(C.TABLE_NAME))
, #UnionSql)
WITHIN GROUP(ORDER BY C.TABLE_SCHEMA, C.TABLE_NAME)
FROM INFORMATION_SCHEMA.TABLES T
JOIN INFORMATION_SCHEMA.COLUMNS C
ON C.TABLE_SCHEMA = T.TABLE_SCHEMA
AND C.TABLE_NAME = T.TABLE_NAME
WHERE T.TABLE_TYPE = 'BASE TABLE' -- Omit views
AND C.COLUMN_NAME = #ColumnName
)
SET #Sql = #Sql + 'ORDER BY Rows DESC, TableName' + #Newline
--PRINT #Sql
EXEC (#Sql)
I generalized it a bit by adding TABLE_SCHEMA so that it could be used with the AdventureWorks database. See this db<>fiddle for a working demo. Also included is equivalent logic that uses FOR XML instead of STRING_AGG for older SQL Server versions.
Assuming that you are using SQL Server, here is a shorthand way using sp_msforeachtable.
DECLARE #ColumnName NVARCHAR(200) = 'ContactID'
CREATE TABLE #T
(
ColumnName NVARCHAR(200),
TableName NVARCHAR(200),
RecordCount INT
)
INSERT INTO #T (ColumnName, TableName)
SELECT
ColumnName = C.COLUMN_NAME,
TableName = '['+C.TABLE_SCHEMA+'].['+C.TABLE_NAME+']'
FROM
INFORMATION_SCHEMA.COLUMNS C
WHERE
C.COLUMN_NAME LIKE '%' + #ColumnName + '%'
EXEC SP_MSFOREACHTABLE 'IF EXISTS(SELECT * FROM #T WHERE TableName = ''?'') UPDATE #T SET RecordCount = (SELECT COUNT(*) FROM ? ) WHERE TableName = ''?'''
SELECT
ColumnName,TableName,
TableType = CASE
WHEN RecordCount IS NULL
THEN 'View'
ELSE 'Table'
END,
RecordCount
FROM
#T
ORDER BY
CASE WHEN RecordCount IS NULL THEN 'View' ELSE 'Table' END
DROP TABLE #T

iterate over all databases, insert data into temp table and display data [duplicate]

I have a stored procedure which scans all tables in my DB for a certain column (codevalues).
It then prints the distinct values for that column and its table it belongs in.
Each column can belong to many tables.
i.e. codeX can be found in Table A and Table B.
ActualCode in TableA
ActualCode
----------
0
1
2
(3 row(s) affected)
--------------------
ActualCode in TableB
ActualCode
----------
0
(1 row(s) affected)
I am trying to figure out how to scan each row in my results, and then insert that row into a new table in a new database.
For example, i want to grab 0 from below for TableA, and insert a row into a new table and store the Value(0) and the Table name (TableA)
And then do the same for value 1...2 etc, and then repeat the same for the next table.
My query is as this:
DECLARE cursorColumnNames CURSOR FOR SELECT DISTINCT COLUMN_NAME, TABLE_NAME FROM
INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%ActualCode%' AND TABLE_CATALOG = 'db1' AND COLUMN_NAME NOT
IN(select ColumnName from [DataDictionary].[dbo].[Code])
OPEN cursorColumnNames
FETCH NEXT FROM cursorColumnNames INTO #columnName, #tableName;
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #columnName + ' in ' + #tableName;
PRINT ' '
SET #SqlQuery = 'SELECT DISTINCT ' + #columnName + ' FROM ' + #tableName;
EXEC (#SqlQuery);
PRINT '--------------------'
FETCH NEXT FROM cursorColumnNames INTO #columnName, #tableName;
END;
CLOSE cursorColumnNames;
DEALLOCATE cursorColumnNames;
I tried grabbing each top 1 value and then add that and repeat until all data has been transferred.
But my query looks for columns that are not in the second db so after the first iteration, my query returns 0 records.
So i am confused as what to do or try.
I do not want to create a new table, the table already exists.
The table i want to add the individual rows to is defined as this:
CodeInsertID TableName ColumnName CodeNo
4648 TableA ActualCode 0
4647 TableA ActualCode 1
4646 TableA ActualCode 2
4645 TableB ActualCode 0
can u try like this ? its work for me.
Declare #SqlQuery nvarchar(max),
#columnName nvarchar(50),
#tableName nvarchar(50)
Declare #table table (TableName nvarchar(50) , ColumnName nvarchar(50) , CodeNo int)
DECLARE cursorColumnNames CURSOR FOR SELECT DISTINCT COLUMN_NAME, TABLE_NAME FROM
INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%ActualCode%' AND TABLE_CATALOG = 'db1' AND COLUMN_NAME NOT
IN(select ColumnName from [DataDictionary].[dbo].[Code])
OPEN cursorColumnNames
FETCH NEXT FROM cursorColumnNames INTO #columnName, #tableName;
WHILE ##FETCH_STATUS = 0
BEGIN
--PRINT #columnName + ' in ' + #tableName;
--PRINT ' '
SET #SqlQuery = 'SELECT DISTINCT ''' + #tablename+ ''', '''+ #columnName+ ''' , ' + #columnName + ' FROM [' + #tableName + ']';
PRINT #SqlQuery
INSERT INTO #table (TableName,ColumnName,CodeNo)
EXEC (#SqlQuery);
--PRINT '--------------------'
FETCH NEXT FROM cursorColumnNames INTO #columnName, #tableName;
END;
CLOSE cursorColumnNames;
DEALLOCATE cursorColumnNames;
SELECT * from #table
Cursors are really slow, you can do this in one single dynamic statement, which we can build in one shot.
You also need to quote the column and table names with QUOTENAME otherwise your code may not work.
Note: To escape a single quote ' in a string, use ''. Don't get confused about which code is part of the dynamic section and which part is static.
DECLARE #sql nvarchar(max) =
N'INSERT INTO myTABLE (TableName, ColumnName, CodeNo)
' +
(SELECT STRING_AGG(
N'SELECT
N' + QUOTENAME(t.name, '''') + N',
N' + QUOTENAME(c.name, '''') + N',
CAST(' + QUOTENAME(c.name) + N' AS nvarchar(max)) -- or whatever your column type is here
FROM db1.' + QUOTENAME(s.name) + N'.' + QUOTENAME(t.name),
CAST(N'
UNION ALL
' AS nvarchar(max))
FROM db1.sys.tables t
JOIN db1.sys.schemas s ON s.schema_id = t.schema_id
JOIN db1.sys.columns c ON c.object_id = t.object_id
WHERE c.name LIKE N'%ActualCode%'
AND c.name NOT IN (SELECT ColumnName FROM [DataDictionary].[dbo].[Code])
);
-- PRINT #sql; -- for testing
EXEC sp_executesql #sql;
You say you only have SQL Server 2014, so you would have to use either a cursor or FOR XML PATH. You can still build the query, then execute it in one shot:
DECLARE #sql nvarchar(max) =
N'INSERT INTO myTABLE (TableName, ColumnName, CodeNo)
';
DECLARE #cur CURSOR;
SET #cur = CURSOR FAST_FORWARD FOR
SELECT
N'SELECT
N' + QUOTENAME(t.name, '''') + N',
N' + QUOTENAME(c.name, '''') + N',
CAST(' + QUOTENAME(c.name) + N' AS nvarchar(max)) -- or whatever your column type is here
FROM db1.' + QUOTENAME(s.name) + N'.' + QUOTENAME(t.name)
FROM db1.sys.tables t
JOIN db1.sys.schemas s ON s.schema_id = t.schema_id
JOIN db1.sys.columns c ON c.object_id = t.object_id
WHERE c.name LIKE N'%ActualCode%'
AND c.name NOT IN (SELECT ColumnName FROM [DataDictionary].[dbo].[Code])
;
OPEN #cur;
DECLARE #tableSql nvarchar(max);
FETCH NEXT FROM #cur INTO #tableSql;
SET #sql = #sql + #tableSql;
WHILE (##FETCH_STATUS = 0)
BEGIN
FETCH NEXT FROM #cur INTO #tableSql;
SET #sql = #sql + N'
UNION ALL
' + #tableSql;
END;
-- PRINT #sql; -- for testing
EXEC sp_executesql #sql;
There is no need to close or deallocate as it's a local variable and will be closed automatically at the end of the batch

How to store copy each row from one table into another table

I have a stored procedure which scans all tables in my DB for a certain column (codevalues).
It then prints the distinct values for that column and its table it belongs in.
Each column can belong to many tables.
i.e. codeX can be found in Table A and Table B.
ActualCode in TableA
ActualCode
----------
0
1
2
(3 row(s) affected)
--------------------
ActualCode in TableB
ActualCode
----------
0
(1 row(s) affected)
I am trying to figure out how to scan each row in my results, and then insert that row into a new table in a new database.
For example, i want to grab 0 from below for TableA, and insert a row into a new table and store the Value(0) and the Table name (TableA)
And then do the same for value 1...2 etc, and then repeat the same for the next table.
My query is as this:
DECLARE cursorColumnNames CURSOR FOR SELECT DISTINCT COLUMN_NAME, TABLE_NAME FROM
INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%ActualCode%' AND TABLE_CATALOG = 'db1' AND COLUMN_NAME NOT
IN(select ColumnName from [DataDictionary].[dbo].[Code])
OPEN cursorColumnNames
FETCH NEXT FROM cursorColumnNames INTO #columnName, #tableName;
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #columnName + ' in ' + #tableName;
PRINT ' '
SET #SqlQuery = 'SELECT DISTINCT ' + #columnName + ' FROM ' + #tableName;
EXEC (#SqlQuery);
PRINT '--------------------'
FETCH NEXT FROM cursorColumnNames INTO #columnName, #tableName;
END;
CLOSE cursorColumnNames;
DEALLOCATE cursorColumnNames;
I tried grabbing each top 1 value and then add that and repeat until all data has been transferred.
But my query looks for columns that are not in the second db so after the first iteration, my query returns 0 records.
So i am confused as what to do or try.
I do not want to create a new table, the table already exists.
The table i want to add the individual rows to is defined as this:
CodeInsertID TableName ColumnName CodeNo
4648 TableA ActualCode 0
4647 TableA ActualCode 1
4646 TableA ActualCode 2
4645 TableB ActualCode 0
can u try like this ? its work for me.
Declare #SqlQuery nvarchar(max),
#columnName nvarchar(50),
#tableName nvarchar(50)
Declare #table table (TableName nvarchar(50) , ColumnName nvarchar(50) , CodeNo int)
DECLARE cursorColumnNames CURSOR FOR SELECT DISTINCT COLUMN_NAME, TABLE_NAME FROM
INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%ActualCode%' AND TABLE_CATALOG = 'db1' AND COLUMN_NAME NOT
IN(select ColumnName from [DataDictionary].[dbo].[Code])
OPEN cursorColumnNames
FETCH NEXT FROM cursorColumnNames INTO #columnName, #tableName;
WHILE ##FETCH_STATUS = 0
BEGIN
--PRINT #columnName + ' in ' + #tableName;
--PRINT ' '
SET #SqlQuery = 'SELECT DISTINCT ''' + #tablename+ ''', '''+ #columnName+ ''' , ' + #columnName + ' FROM [' + #tableName + ']';
PRINT #SqlQuery
INSERT INTO #table (TableName,ColumnName,CodeNo)
EXEC (#SqlQuery);
--PRINT '--------------------'
FETCH NEXT FROM cursorColumnNames INTO #columnName, #tableName;
END;
CLOSE cursorColumnNames;
DEALLOCATE cursorColumnNames;
SELECT * from #table
Cursors are really slow, you can do this in one single dynamic statement, which we can build in one shot.
You also need to quote the column and table names with QUOTENAME otherwise your code may not work.
Note: To escape a single quote ' in a string, use ''. Don't get confused about which code is part of the dynamic section and which part is static.
DECLARE #sql nvarchar(max) =
N'INSERT INTO myTABLE (TableName, ColumnName, CodeNo)
' +
(SELECT STRING_AGG(
N'SELECT
N' + QUOTENAME(t.name, '''') + N',
N' + QUOTENAME(c.name, '''') + N',
CAST(' + QUOTENAME(c.name) + N' AS nvarchar(max)) -- or whatever your column type is here
FROM db1.' + QUOTENAME(s.name) + N'.' + QUOTENAME(t.name),
CAST(N'
UNION ALL
' AS nvarchar(max))
FROM db1.sys.tables t
JOIN db1.sys.schemas s ON s.schema_id = t.schema_id
JOIN db1.sys.columns c ON c.object_id = t.object_id
WHERE c.name LIKE N'%ActualCode%'
AND c.name NOT IN (SELECT ColumnName FROM [DataDictionary].[dbo].[Code])
);
-- PRINT #sql; -- for testing
EXEC sp_executesql #sql;
You say you only have SQL Server 2014, so you would have to use either a cursor or FOR XML PATH. You can still build the query, then execute it in one shot:
DECLARE #sql nvarchar(max) =
N'INSERT INTO myTABLE (TableName, ColumnName, CodeNo)
';
DECLARE #cur CURSOR;
SET #cur = CURSOR FAST_FORWARD FOR
SELECT
N'SELECT
N' + QUOTENAME(t.name, '''') + N',
N' + QUOTENAME(c.name, '''') + N',
CAST(' + QUOTENAME(c.name) + N' AS nvarchar(max)) -- or whatever your column type is here
FROM db1.' + QUOTENAME(s.name) + N'.' + QUOTENAME(t.name)
FROM db1.sys.tables t
JOIN db1.sys.schemas s ON s.schema_id = t.schema_id
JOIN db1.sys.columns c ON c.object_id = t.object_id
WHERE c.name LIKE N'%ActualCode%'
AND c.name NOT IN (SELECT ColumnName FROM [DataDictionary].[dbo].[Code])
;
OPEN #cur;
DECLARE #tableSql nvarchar(max);
FETCH NEXT FROM #cur INTO #tableSql;
SET #sql = #sql + #tableSql;
WHILE (##FETCH_STATUS = 0)
BEGIN
FETCH NEXT FROM #cur INTO #tableSql;
SET #sql = #sql + N'
UNION ALL
' + #tableSql;
END;
-- PRINT #sql; -- for testing
EXEC sp_executesql #sql;
There is no need to close or deallocate as it's a local variable and will be closed automatically at the end of the batch

SQL query to dynamically COUNT(FIELD) for all fields of table X

This should be such an easy thing, but it has me totally stumped.
You can easily return the count of each field of a table manually, with oneliners such as:
select count(FIELD1) from TABLE1 --42,706
select count(FIELD5) from TABLE1 --42,686
select count(FIELD9) from TABLE1 --2,918
This is slow and painful if you want to review several dozen tables the same way, and requires you to know the names of the fields in advance.
How handy would it be to have a script you can connect to any database, simply feed it a table name, and it will automatically return the counts for each field of that table?
Seems you can get half the work done with:
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'TABLE1'
Something is flawed even with my barebones approach (explicitly hitting one field instead of them all):
declare #TABLENAME varchar(30), #FIELDNAME varchar(30)
set #TABLENAME = 'TABLE1'
set #FIELDNAME = (select top 1 COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = #TABLENAME
and COLUMN_NAME = 'FIELD9')
select #FIELDNAME, count(#FIELDNAME) from TABLE1
The result is 42,706. Recall from my example above that FIELD9 only contains 2,918 values.
Even if that wasn't a problem, the more dynamic query would replace the last line with:
select #FIELDNAME, count(#FIELDNAME) from #TABLENAME
But SQL Server returns:
Must declare the table variable "#TABLENAME".
So I can avoid that by restructuring the query with a temp table:
declare #FIELDNAME varchar(30)
set #FIELDNAME = (select top 1 COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'TABLE1'
and COLUMN_NAME = 'FIELD9')
if OBJECT_ID('TEMPDB..#TEMP1') is not null
drop table #TEMP1
select *
into #TEMP1
from TABLE1 --still not exactly dynamic!
select #FIELDNAME, count(#FIELDNAME) from #TEMP1
But that still brings us back to the original problem of returning 42,706 instead of 2,918.
I am running SQL Server 2008 R2, if it makes any difference.
Your query:
SELECT #FIELDNAME, COUNT(#FIELDNAME) FROM TABLE1
does not count FIELD9, #FIELDNAME is treated as a constant. It's like doing a COUNT(*).
You should use dynamic sql:
DECLARE #sql VARCHAR(MAX)
SET #sql = 'SELECT ''' + #fieldName + ''', COUNT([' + #fieldName + ']) FROM [' + #tableName + ']'
EXEC(#sql)
To get all columns and return it in a single result set without using a Temporary Table and CURSOR:
DECLARE #sql NVARCHAR(MAX) = ''
SELECT #sql = #sql +
'SELECT ''' + COLUMN_NAME + ''' AS ColName, COUNT([' + COLUMN_NAME + ']) FROM [' + #tableName + ']' + CHAR(10) +
'UNION ALL' + CHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #tableName
SELECT #sql = LEFT(#sql, LEN(#sql) - 10)
EXEC(#sql)
Just set the #TargetTableName will do the job
DECLARE #TargetTableName sysname = '*'
SET NOCOUNT ON
DECLARE #TableName sysname, #ColumnName sysname, #Sql nvarchar(max)
DECLARE #TableAndColumn table
(
TableName sysname,
ColumnName sysname
)
DECLARE #Result table
(
TableName sysname,
ColumnName sysname,
NonNullRecords int
)
INSERT #TableAndColumn
SELECT o.name, c.name FROM sys.objects o INNER JOIN sys.columns c ON o.object_id = c.object_id
WHERE (o.name = #TargetTableName OR #TargetTableName = '*') AND o.type = 'U' AND c.system_type_id NOT IN (34, 35, 99) -- 34:image 35:text 99:ntext
ORDER BY c.column_id
DECLARE column_cursor CURSOR FOR SELECT TableName, ColumnName FROM #TableAndColumn
OPEN column_cursor
FETCH NEXT FROM column_cursor
INTO #TableName, #ColumnName
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #Sql = 'SELECT ''' + #TableName + ''' AS TableName, ''' + #ColumnName + ''' AS ColumnName, COUNT([' + #ColumnName + ']) AS NonNullRecords FROM [' + #TableName + ']'
print #Sql
INSERT #Result
EXEC (#Sql)
FETCH NEXT FROM column_cursor
INTO #TableName, #ColumnName
END
CLOSE column_cursor;
DEALLOCATE column_cursor;
SET NOCOUNT OFF
SELECT * FROM #Result

Need to fetch ID using stored procedure in SQL Server

CREATE TABLE myTable99 (TABLE_NAME sysname, COLUMN_NAME sysname, Occurs int)
GO
SET NOCOUNT ON
DECLARE #SQL varchar(8000),
#TABLE_NAME sysname,
#COLUMN_NAME sysname,
#Sargable varchar(80),
#Count int
SELECT #Sargable = 'PS'
DECLARE insaneCursor CURSOR FOR
SELECT c.TABLE_NAME, c.COLUMN_NAME
FROM INFORMATION_SCHEMA.Columns c INNER JOIN INFORMATION_SCHEMA.Tables t
ON t.TABLE_SCHEMA = c.TABLE_SCHEMA AND t.TABLE_NAME = c.TABLE_NAME
WHERE c.DATA_TYPE IN ('char','nchar','varchar','nvarchar','text','ntext')
AND t.TABLE_TYPE = 'BASE TABLE'
OPEN insaneCursor
FETCH NEXT FROM insaneCursor INTO #TABLE_NAME, #COLUMN_NAME
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #SQL = 'INSERT INTO myTable99 (TABLE_NAME, COLUMN_NAME, Occurs) SELECT '
+ '''' + #TABLE_NAME + '''' + ','
+ '''' + #COLUMN_NAME + '''' + ','
+ 'COUNT(*) FROM [' + #TABLE_NAME
+ '] WHERE [' + #COLUMN_NAME + '] Like '
+ ''''+ '%' + #Sargable + '%' + ''''
--SELECT #SQL
EXEC(#SQL)
IF ##ERROR <> 0
------ <> means Not Equal To
BEGIN
SELECT #SQL
SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = #TABLE_NAME
GOTO Error
END
FETCH NEXT FROM insaneCursor INTO #TABLE_NAME, #COLUMN_NAME
END
SELECT * FROM myTable99 WHERE Occurs <> 0
Error:
CLOSE insaneCursor
DEALLOCATE insaneCursor
GO
DROP TABLE myTable99
GO
SET NOCOUNT OFF
The following stored procedure will search for the string 'PS' and will return the COLUMN_NAME and TABLE_NAME but I want the ID value of the PS in corresponding column
ex:
ID NAME
2 PW
3 PS
now stored procedure only returns COLUMN_NAME,TABLE_NAME but I need the ID that is 3 when I search for string 'PS' along with COLUMN_NAME and TABLE_NAME
I tried with
SELECT #SQL = 'INSERT INTO myTable99 (TABLE_NAME, COLUMN_NAME, Occurs) SELECT *'
+ 'FROM [' + #TABLE_NAME
+ '] WHERE [' + #COLUMN_NAME + '] Like '
+ ''''+ '%' + #Sargable + '%' + ''''
but the stored procedure returned all table and column name in database even if the string is not found in table
myTable99
TABLE_NAME COLUMN_NAME Occurs
project projectname 2
task name 1
Now I need a new column with name ID which fetches the ID of the projectname 'PS' in table project
Expected result:
Suppose table Project has PS entry
Table name: Project
Columns:
ID projectname
2 PR
3 PS
Now the stored procedure will return the Table_Name=Project,column_Name=projectname but not the Id, I need ID of the string PS that is 3
Result: when I search for string='PS'
ID TABLE_NAME COLUMN_NAME Occurs
3 Project projectname 1
Your question is not very clear, I think you need to bring the projectId along with rest of the columns in myTable99. You can do following.
--++++++++++++++++++++++++++++++++++++++++++++++++
--Before/after your cursor (not within the cursor)
DECLARE #ProjectId INT
--Assuming projectName as a unique constraint
SELECT #ProjectId = ProjectId
FROM yourProjectTable
WHERE projectName = #Sargable
--++++++++++++++++++++++++++++++++++++++++++++++++
--At the end, replace your select query with
SELECT TABLE_NAME, COLUMN_NAME, Occurs, #ProjectId ProjectId
FROM myTable99
WHERE Occurs <> 0