Search for a particular string in an entire database [duplicate] - sql

I know it's possible, but I don't know how.
I need to search an SQL Server database for all mentions of a specific string.
For example: I would like to search all tables, views, functions, stored procedures, ... for string "tblEmployes" (not data within the tables).
One of the reasons I need this is I would like to remove some extra data tables that are created, but I am afraid that they are maybe used somewhere in procedures or functions.

This will search every column of every table in a specific database. Create the stored procedure on the database that you want to search in.
The Ten Most Asked SQL Server Questions And Their Answers:
CREATE PROCEDURE FindMyData_String
#DataToFind NVARCHAR(4000),
#ExactMatch BIT = 0
AS
SET NOCOUNT ON
DECLARE #Temp TABLE(RowId INT IDENTITY(1,1), SchemaName sysname, TableName sysname, ColumnName SysName, DataType VARCHAR(100), DataFound BIT)
INSERT INTO #Temp(TableName,SchemaName, ColumnName, DataType)
SELECT C.Table_Name,C.TABLE_SCHEMA, C.Column_Name, C.Data_Type
FROM Information_Schema.Columns AS C
INNER Join Information_Schema.Tables AS T
ON C.Table_Name = T.Table_Name
AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
WHERE Table_Type = 'Base Table'
And Data_Type In ('ntext','text','nvarchar','nchar','varchar','char')
DECLARE #i INT
DECLARE #MAX INT
DECLARE #TableName sysname
DECLARE #ColumnName sysname
DECLARE #SchemaName sysname
DECLARE #SQL NVARCHAR(4000)
DECLARE #PARAMETERS NVARCHAR(4000)
DECLARE #DataExists BIT
DECLARE #SQLTemplate NVARCHAR(4000)
SELECT #SQLTemplate = CASE WHEN #ExactMatch = 1
THEN 'If Exists(Select *
From ReplaceTableName
Where Convert(nVarChar(4000), [ReplaceColumnName])
= ''' + #DataToFind + '''
)
Set #DataExists = 1
Else
Set #DataExists = 0'
ELSE 'If Exists(Select *
From ReplaceTableName
Where Convert(nVarChar(4000), [ReplaceColumnName])
Like ''%' + #DataToFind + '%''
)
Set #DataExists = 1
Else
Set #DataExists = 0'
END,
#PARAMETERS = '#DataExists Bit OUTPUT',
#i = 1
SELECT #i = 1, #MAX = MAX(RowId)
FROM #Temp
WHILE #i <= #MAX
BEGIN
SELECT #SQL = REPLACE(REPLACE(#SQLTemplate, 'ReplaceTableName', QUOTENAME(SchemaName) + '.' + QUOTENAME(TableName)), 'ReplaceColumnName', ColumnName)
FROM #Temp
WHERE RowId = #i
PRINT #SQL
EXEC SP_EXECUTESQL #SQL, #PARAMETERS, #DataExists = #DataExists OUTPUT
IF #DataExists =1
UPDATE #Temp SET DataFound = 1 WHERE RowId = #i
SET #i = #i + 1
END
SELECT SchemaName,TableName, ColumnName
FROM #Temp
WHERE DataFound = 1
GO
To run it, just do this:
exec FindMyData_string 'google', 0
It works amazingly well!!!

If you need to find database objects (e.g. tables, columns, and triggers) by name - have a look at the free Redgate Software tool called SQL Search which does this - it searches your entire database for any kind of string(s).
It's a great must-have tool for any DBA or database developer - did I already mention it's absolutely free to use for any kind of use??

You can also try ApexSQL Search – it’s a free SSMS add-in similar to SQL Search.
If you really want to use only SQL you might want to try this script:
select
S.name as [Schema],
o.name as [Object],
o.type_desc as [Object_Type],
C.text as [Object_Definition]
from sys.all_objects O inner join sys.schemas S on O.schema_id = S.schema_id
inner join sys.syscomments C on O.object_id = C.id
where S.schema_id not in (3,4) -- avoid searching in sys and INFORMATION_SCHEMA schemas
and C.text like '%ICE_%'
order by [Schema]

You can export your database (if small) to your hard drive / desktop, and then just do a string search via a text search program or text editor.

For getting a table by name in SQL Server:
SELECT *
FROM sys.Tables
WHERE name LIKE '%Employees%'
For finding a stored procedure by name:
SELECT name
FROM sys.objects
WHERE name = 'spName'
To get all stored procedures related to a table:
----Option 1
SELECT DISTINCT so.name
FROM syscomments sc
INNER JOIN sysobjects so ON sc.id=so.id
WHERE sc.TEXT LIKE '%tablename%'
----Option 2
SELECT DISTINCT o.name, o.xtype
FROM syscomments c
INNER JOIN sysobjects o ON c.id=o.id
WHERE c.TEXT LIKE '%tablename%'

This code searching procedure and function but not search in table :)
SELECT name
FROM sys.all_objects
WHERE Object_definition(object_id)
LIKE '%text%'
ORDER BY name

You could;
Script the database to a single file and search the file for tblEmployees using a text editor. In SQL Server Management Studio (SSMS), right click over the database and choose Generate Scripts.
Use SSMS 'View Dependencies' by right clicking over tblEmployees to see which other objects are dependent on it
Use a free third-party tool such as Redgate Software's SQL Search to search all database objects by name and content by keyword.

My version...
I named it "Needle in the haystack" for obvious reasons.
It searches for a specific value in each row and each column, not for column names, etc.
Execute search (replace values for the first two variables of course):
DECLARE #SEARCH_DB VARCHAR(100)='REPLACE_WITH_YOUR_DB_NAME'
DECLARE #SEARCH_VALUE_LIKE NVARCHAR(100)=N'%REPLACE_WITH_SEARCH_STRING%'
SET NOCOUNT ON;
DECLARE col_cur CURSOR FOR
SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM information_schema.columns WHERE TABLE_CATALOG=#SEARCH_DB AND DATA_TYPE NOT IN ('timestamp', 'datetime');
DECLARE #TOTAL int = (SELECT COUNT(*)
FROM information_schema.columns WHERE TABLE_CATALOG=#SEARCH_DB AND DATA_TYPE NOT IN ('timestamp', 'datetime'));
DECLARE #TABLE_CATALOG nvarchar(500), #TABLE_SCHEMA nvarchar(500), #TABLE_NAME nvarchar(500), #COLUMN_NAME nvarchar(500), #DATA_TYPE nvarchar(500);
DECLARE #SQL nvarchar(4000)='';
PRINT '-------- BEGIN SEARCH --------';
OPEN col_cur;
FETCH NEXT FROM col_cur INTO #TABLE_CATALOG, #TABLE_SCHEMA, #TABLE_NAME, #COLUMN_NAME, #DATA_TYPE;
BEGIN TRY DROP TABLE ##RESULTS; END TRY BEGIN CATCH END CATCH
CREATE TABLE ##RESULTS( TABLE_CATALOG nvarchar(500), TABLE_SCHEMA nvarchar(500), TABLE_NAME nvarchar(500), COLUMN_NAME nvarchar(500), DATA_TYPE nvarchar(500), RECORDS int)
DECLARE #SHOULD_CAST bit=0
DECLARE #i int =0
DECLARE #progress_sum bigint=0
WHILE ##FETCH_STATUS = 0
BEGIN
-- PRINT '' + CAST(#i as varchar(100)) +' of ' + CAST(#TOTAL as varchar(100)) + ' ' + #TABLE_CATALOG+'.'+#TABLE_SCHEMA+'.'+#TABLE_NAME+': '+#COLUMN_NAME+' ('+#DATA_TYPE+')';
SET #SHOULD_CAST = (SELECT CASE #DATA_TYPE
WHEN 'varchar' THEN 0
WHEN 'nvarchar' THEN 0
WHEN 'char' THEN 0
ELSE 1 END)
SET #SQL='SELECT '''+#TABLE_CATALOG+''' catalog_name, '''+#TABLE_SCHEMA+''' schema_name, '''+#TABLE_NAME+''' table_name, '''+#COLUMN_NAME+''' column_name, '''+#DATA_TYPE+''' data_type, ' +
+' COUNT(['+#COLUMN_NAME+']) records '+
+' FROM '+#TABLE_CATALOG+'.'+#TABLE_SCHEMA+'.'+#TABLE_NAME +
+' WHERE ' + CASE WHEN #SHOULD_CAST=1 THEN 'CAST(['+#COLUMN_NAME + '] as NVARCHAR(max)) ' ELSE ' ['+#COLUMN_NAME + '] ' END
+' LIKE '''+ #SEARCH_VALUE_LIKE + ''' '
-- PRINT #SQL;
IF #i % 100 = 0
BEGIN
SET #progress_sum = (SELECT SUM(RECORDS) FROM ##RESULTS)
PRINT CAST (#i as varchar(100)) +' of ' + CAST(#TOTAL as varchar(100)) +': '+ CAST (#progress_sum as varchar(100))
END
INSERT INTO ##RESULTS (TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE, RECORDS)
EXEC(#SQL)
FETCH NEXT FROM col_cur INTO #TABLE_CATALOG, #TABLE_SCHEMA, #TABLE_NAME, #COLUMN_NAME, #DATA_TYPE;
SET #i=#i+1
-- IF #i > 1000
-- BREAK
END
CLOSE col_cur;
DEALLOCATE col_cur;
SELECT * FROM ##RESULTS WHERE RECORDS>0;
Then to view results, even while executing, from another window, execute:
DECLARE #SEARCH_VALUE_LIKE NVARCHAR(100)=N'%#FLEX#%'
SELECT * FROM ##RESULTS WHERE RECORDS>0;
SET NOCOUNT ON;
DECLARE col_cur CURSOR FOR
SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM ##RESULTS WHERE RECORDS>0;
DECLARE #TABLE_CATALOG nvarchar(500), #TABLE_SCHEMA nvarchar(500), #TABLE_NAME nvarchar(500), #COLUMN_NAME nvarchar(500), #DATA_TYPE nvarchar(500);
DECLARE #SQL nvarchar(4000)='';
OPEN col_cur;
FETCH NEXT FROM col_cur INTO #TABLE_CATALOG, #TABLE_SCHEMA, #TABLE_NAME, #COLUMN_NAME, #DATA_TYPE;
DECLARE #i int =0
DECLARE #SHOULD_CAST bit=0
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SHOULD_CAST = (SELECT CASE #DATA_TYPE
WHEN 'varchar' THEN 0
WHEN 'nvarchar' THEN 0
WHEN 'char' THEN 0
ELSE 1 END)
SET #SQL='SELECT '''+#TABLE_CATALOG+''' catalog_name, '''+#TABLE_SCHEMA+''' schema_name, '''+#TABLE_NAME+''' table_name, '''+#COLUMN_NAME+''' column_name, '''+#DATA_TYPE+''' data_type, ' +
+' ['+#COLUMN_NAME+']'+
+', * '
+' FROM '+#TABLE_CATALOG+'.'+#TABLE_SCHEMA+'.'+#TABLE_NAME +
+' WHERE ' + CASE WHEN #SHOULD_CAST=1 THEN 'CAST(['+#COLUMN_NAME + '] as NVARCHAR(max)) ' ELSE ' ['+#COLUMN_NAME + '] ' END
+' LIKE '''+ #SEARCH_VALUE_LIKE + ''' '
PRINT #SQL;
EXEC(#SQL)
FETCH NEXT FROM col_cur INTO #TABLE_CATALOG, #TABLE_SCHEMA, #TABLE_NAME, #COLUMN_NAME, #DATA_TYPE;
SET #i=#i+1
-- IF #i > 10
-- BREAK
END
CLOSE col_cur;
DEALLOCATE col_cur;
Few mentions about it:
it uses cursors instead of a blocking while loop
it can print progress (uncomment if needed)
it can exit after a few attempts (uncomment the IF at the end)
it displays all records
you can fine tune it as needed
DISCLAIMERS:
DO NOT run it in production environments!
It is slow. If the DB is accessed by other services/users, please add " WITH (NOLOCK) " after every table name in all the selects, especially the dynamic select ones.
It does not validate/protect against all sorts of SQL injection options.
If your DB is huge, prepare yourself for some sleep, make sure the query will not be killed after a few minutes.
It casts some values to string, including ints/bigints/smallints/tinyints. If you don't need those, put them at the same exclusion lists with the timestamps at the top of the script.

The content of all stored procedures, views and functions are stored in field text of table sysComments. The name of all objects are stored in table sysObjects and the columns are in sysColumns.
Having this information, you can use this code to search in content of views, stored procedures, and functions for the specified word:
Select b.name from syscomments a
inner join sysobjects b on a.id = b.id
where text like '%tblEmployes%'
This query will give you the objects which contains the word "tblEmployes" .
To search by the name of Objects you can use this code:
Select name from sysobjects
where name like '%tblEmployes%'
And finally to find the objects having at least one column containing the word "tblEmployes", you can use this code:
Select b.name from syscolumns a inner join sysobjects b on a.id = b.id
where a.name like '%tblEmployes%'
You can combine these three queries with union:
Select distinct b.name from syscomments a
inner join sysobjects b on a.id = b.id
where text like '%tblEmployes%'
union
Select distinct name from sysobjects
where name like '%tblEmployes%'
union
Select distinct b.name from syscolumns a inner join sysobjects b on a.id = b.id
where a.name like '%tblEmployes%'
With this query you have all objects containing the word "tblEmployes" in content or name or as a column.

I was given access to a database, but not the table where my query was being stored in.
Inspired by #marc_s answer, I had a look at HeidiSQL which is a Windows program that can deal with MySQL, SQL Server, and PostgreSQL.
I found that it can also search a database for a string.
It will search each table and give you how many times it found the string per table!

This will search for a string over every database:
declare #search_term varchar(max)
set #search_term = 'something'
select #search_term = 'use ? SET QUOTED_IDENTIFIER ON
select
''[''+db_name()+''].[''+c.name+''].[''+b.name+'']'' as [object],
b.type_desc as [type],
d.obj_def.value(''.'',''varchar(max)'') as [definition]
from (
select distinct
a.id
from sys.syscomments a
where a.[text] like ''%'+#search_term+'%''
) a
inner join sys.all_objects b
on b.[object_id] = a.id
inner join sys.schemas c
on c.[schema_id] = b.[schema_id]
cross apply (
select
[text()] = a1.[text]
from sys.syscomments a1
where a1.id = a.id
order by a1.colid
for xml path(''''), type
) d(obj_def)
where c.schema_id not in (3,4) -- avoid searching in sys and INFORMATION_SCHEMA schemas
and db_id() not in (1,2,3,4) -- avoid sys databases'
if object_id('tempdb..#textsearch') is not null drop table #textsearch
create table #textsearch
(
[object] varchar(300),
[type] varchar(300),
[definition] varchar(max)
)
insert #textsearch
exec sp_MSforeachdb #search_term
select *
from #textsearch
order by [object]

If I want to find where anything I want to search is, I use this:
DECLARE #search_string varchar(200)
SET #search_string = '%myString%'
SELECT DISTINCT
o.name AS Object_Name,
o.type_desc,
m.definition
FROM sys.sql_modules m
INNER JOIN
sys.objects o
ON m.object_id = o.object_id
WHERE m.definition Like #search_string;

It's easy to search a string in your database with phpmyadmin. There you can chose from many search options and you can see where your search phrase is mentioned.

Here is the same script as submitted by user l--''''''---------'''''''''''', but corrected to work on a case-sensitive SQL instance, and with some other minor improvements.
DROP PROCEDURE IF EXISTS dbo.spFind_Text_In_Database
GO
CREATE PROCEDURE dbo.spFind_Text_In_Database
#strText_To_Find NVARCHAR(4000),
#bitExact_Match BIT = 0
AS
SET NOCOUNT ON
DECLARE #Temp TABLE(RowId INT IDENTITY(1,1), SchemaName sysname, TableName sysname, ColumnName SysName, DataType VARCHAR(100), DataFound BIT)
INSERT INTO #Temp(TableName,SchemaName, ColumnName, DataType)
SELECT C.TABLE_NAME, C.TABLE_SCHEMA, C.COLUMN_NAME, C.DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS AS C
INNER Join INFORMATION_SCHEMA.TABLES AS T
ON C.TABLE_NAME = T.TABLE_NAME
AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
WHERE TABLE_TYPE = 'BASE TABLE'
And DATA_TYPE In ('ntext','text','nvarchar','nchar','varchar','char')
DECLARE #i INT
DECLARE #MAX INT
DECLARE #TableName sysname
DECLARE #ColumnName sysname
DECLARE #SchemaName sysname
DECLARE #SQL NVARCHAR(4000)
DECLARE #PARAMETERS NVARCHAR(4000)
DECLARE #DataExists BIT
DECLARE #SQLTemplate NVARCHAR(4000)
SELECT #SQLTemplate = CASE WHEN #bitExact_Match = 1
THEN 'If Exists(Select *
From ReplaceTableName
Where Convert(nVarChar(4000), [ReplaceColumnName])
= ''' + #strText_To_Find + '''
)
Set #DataExists = 1
Else
Set #DataExists = 0'
ELSE 'If Exists(Select *
From ReplaceTableName
Where Convert(nVarChar(4000), [ReplaceColumnName])
Like ''%' + #strText_To_Find + '%''
)
Set #DataExists = 1
Else
Set #DataExists = 0'
END,
#PARAMETERS = '#DataExists Bit OUTPUT',
#i = 1
SELECT #i = 1, #MAX = MAX(RowId)
FROM #Temp
WHILE #i <= #MAX
BEGIN
SELECT #SQL = REPLACE(REPLACE(#SQLTemplate, 'ReplaceTableName', QUOTENAME(SchemaName) + '.' + QUOTENAME(TableName)), 'ReplaceColumnName', ColumnName)
FROM #Temp
WHERE RowId = #i
PRINT #SQL
EXEC sp_executesql #SQL, #PARAMETERS, #DataExists = #DataExists OUTPUT
IF #DataExists =1
UPDATE #Temp SET DataFound = 1 WHERE RowId = #i
SET #i = #i + 1
END
SELECT SchemaName,TableName, ColumnName
FROM #Temp
WHERE DataFound = 1
GO

Searching SQL Database objects is possible with SQL Server Management Studio (SSMS) with the following methods, with SSMS Object Search: object explorer details or T-SQL scripts as explained in following:
Different ways to search for SQL Server database objects
SQL Server Find Anything in Object Explorer in SSMS
Search text with wildcards

Here is how you can search the database in Swift using the FMDB library.
First, go to this link and add this to your project: FMDB. When you have done that, then here is how you do it. For example, you have a table called Person, and you have firstName and secondName and you want to find data by first name, here is a code for that:
func loadDataByfirstName(firstName : String, completion: #escaping CompletionHandler){
if isDatabaseOpened {
let query = "select * from Person where firstName like '\(firstName)'"
do {
let results = try database.executeQuery(query, values: [firstName])
while results.next() {
let firstName = results.string(forColumn: "firstName") ?? ""
let lastName = results.string(forColumn: "lastName") ?? ""
let newPerson = Person(firstName: firstName, lastName: lastName)
self.persons.append(newPerson)
}
completion(true)
}catch let err {
completion(false)
print(err.localizedDescription)
}
database.close()
}
}
Then in your ViewController you will write this to find the person detail you are looking for:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
SQLManager.instance.openDatabase { (success) in
if success {
SQLManager.instance.loadDataByfirstName(firstName: "Hardi") { (success) in
if success {
// You have your data Here
}
}
}
}
}

Related

How to get metadata from columns that have specific number of distinct values?

I need to find all columns that have 5 or more distinct values. Now my query is like:
SELECT TABLE_NAME,COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'MY_SCHEMA'
AND TABLE_NAME IN ('TABLE_1', 'TABLE_2', 'TABLE_3')
I thought it could be done like simple subquery. Something like:
*code above*
AND (select count(distinct COLUMN_NAME) FROM TABLE_SCHEMA + TABLE_NAME) > 5
I just recently started to learn SQL and thought this kind of thing is easy, but still I can't figure out right query.
With help of Stu's answer and this answer I was able to make workable solution.
declare #RowsToProcess int
declare #CurrentRow int
declare #SelectCol nvarchar(max)
declare #SelectTable nvarchar(max)
declare #tablesAndColumns table(RowID int not null primary key identity(1,1), table_name nvarchar(max), column_name nvarchar(max)
insert into #tablesAndColumns
select TABLE_NAME,COLUMN_NAME,DATA_TYPE
from INFORMATION_SCHEMA.COLUMNS
where TABLE_SCHEMA = 'my schema'
and TABLE_NAME in ('myTable', 'myTable2' ,'myTable3')
set #RowsToProcess=##ROWCOUNT
set #CurrentRow=0
while #CurrentRow<#RowsToProcess
begin
set #CurrentRow=#CurrentRow+1
select
#SelectCol=column_name,
#SelectTable=table_name
from #tablesAndColumns
where RowID=#CurrentRow
declare #QRY NVARCHAR(MAX)
set #QRY = ' insert into [my_schema].[result_table] (table_name,column_name,distinct_values)
SELECT ' + '''' +#SelectTable+ '''' + ', ' + '''' +#SelectCol+ '''' + ', count(*) as cnt
FROM (SELECT DISTINCT ' +#SelectCol+ ' FROM my_schema.'+ #SelectTable+') as a'
exec SP_EXECUTESQL #QRY
end
I'd like to propose another way. You can run through all the column and table names by using a CURSOR. That way you don't need to store them beforehand and can directly access them in your loop while also having a while condition.
Also I went with sys.tables and sys.columns since I noticed that INFORMATION_SCHEMA also contains views and sys.tables can be filtered for the table's type.
I added a "HAVING COUNT(*) >= 5" into the dynamic SQL so I don't save those informations in the first place rather than filtering them later.
Finally I went with "(NOLOCK)" because you only try to acces the tables for reading and that way you don't lock them for other users / interactions.
(The #i and #max are just for tracking the progress since I ran the query on ~10k columns and just wanted to see how far it is.)
Hopefully might be helpful aswell although you seem to have solved your problem.
DECLARE #columnName nvarchar(100),
#tableName nvarchar(100),
#sql nvarchar(MAX),
#i int = 0,
#max int = (SELECT COUNT(*)
FROM sys.tables T
INNER JOIN sys.columns C ON T.object_id = C.object_id
WHERE T.[type] = 'U')
DROP TABLE IF EXISTS #resultTable
CREATE TABLE #resultTable (ColumnName nvarchar(100), TableName nvarchar(100), ResultCount int)
DECLARE db_cursor CURSOR FOR
SELECT C.[name], T.[name]
FROM sys.tables T
INNER JOIN sys.columns C ON T.object_id = C.object_id
WHERE T.[type] = 'U'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #columnName, #tableName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = CONCAT(' INSERT INTO #resultTable (ColumnName, TableName, ResultCount)
SELECT ''', #columnName, ''', ''', #tableName, ''', COUNT(*)
FROM (
SELECT DISTINCT [', #columnName, ']
FROM [', #tableName, '] (NOLOCK)
WHERE [', #columnName, '] IS NOT NULL
) t
HAVING COUNT(*) >= 5')
EXEC sp_executesql #sql
SET #i = #i + 1
PRINT CONCAT(#i, ' / ', #max)
FETCH NEXT FROM db_cursor INTO #columnName, #tableName
END
CLOSE db_cursor
DEALLOCATE db_cursor
SELECT *
FROM #resultTable

How to use loop for like or ilike function?

I am currently asked to validate the result of a global search which to find all records containing some keywords cross whole database. To do so, I need to check all the rows in each table that have keywords. The result for this global search is ready and partially of the result looks like the one below:
table_name
column_name
keyword
cnt
Wf_Process
Name_EN
FEC
11
Wf_Process
FTABLENAME
GB
14
ICCClass
Name_EN
GB
4
What I am trying to do is using the 'like' operator to extract all the data in each table where columns containing keywords. That is, I will use query such as:
select distinct Name_EN, FTABLENAME from Wf_Process where Name_EN like '%FEC%' or FTABLENAME like '%GB%'
and
select distinct Name_EN from ICCClass where Name_EN like '%GB%'
to pull out all data I need in whole database. If I only have three records, then it is not a problem. However my result returned over thousands tables have more than 10K rows containing keywords in total. Therefore, I was trying to use a loop to do this mission but I failed.
My question therefore is, does anyone have any idea to write a loop to do the 'like' search for all the tables in one time? Or is there another way rather than loop can do this in SQL Server?
Thank you very much!
You need dynamic SQL for this. You can generate a big UNION ALL query of all the tables together.
DECLARE #sql nvarchar(max) = (
SELECT STRING_AGG(CAST('
SELECT
' + QUOTENAME(con.table_name, '''') + ' table_name,
' + QUOTENAME(con.column_name, '''') + ' column_name,
' + QUOTENAME(con.keyword, '''') + ' keyword,
COUNT(*) cnt
FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ' t
WHERE t.' + QUOTENAME(c.name) + ' LIKE ' + QUOTENAME('%' + con.keyword + '%', '''')
AS nvarchar(max)), '
UNION ALL')
FROM YourConditions con
JOIN sys.tables t ON t.table_name
JOIN sys.schemas s ON s.schema_id = t.schema_id
JOIN sys.columns c ON c.object_id = t.object_id
WHERE t.name = con.table_name
AND c.name = con.column_name
);
PRINT #sql; -- your friend
EXEC sp_executesql #sql;
There are more efficient ways to do this if there are many columns or keywords per table, but this should get you started.
The question looks odd, thou can be done via dynamic sql, but not as a regular solution more like a one off or POC/test.
use tempdb
GO
drop table if exists search_result
go
create table search_result (
table_name sysname
,column_name sysname
,keyword varchar(100))
go
insert into search_result values
('Wf_Process', 'Name_EN', 'FEC')
,('Wf_Process' , 'FTABLENAME', 'GB')
,('ICCClass', 'Name_EN', 'GB')
GO
drop table if exists result
create table result (val varchar(500))
go
declare #col sysname
declare #tab sysname
declare #kw varchar(100)
declare #sql varchar(1000)
while exists (select * from search_result)
begin
select top 1
#tab = table_name
, #col = column_name
, #kw = keyword
from search_result
set #sql = concat('insert into result select ', #col, ' from ', #tab, ' where ', #col, ' like ''%', #kw, '%''' )
print(#sql)
exec (#sql)
delete from search_result
where table_name = #tab and column_name = #col and keyword = #kw
end
GO
select * from result
--initially trying to get all the column name with its respective table name, finding out if there is that particular keyword in all table,
--if yes, insert into temp table, if there aint keyword, it will insert the record too but the count of record will be zero.
--trying to make it dynamic and running it inside the loop by assigning row number to each table with different column.
IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL
DROP TABLE #TEMP
CREATE TABLE #TEMP (TABLE_NAME NVARCHAR(200), COLUMN_NAME NVARCHAR(200), KEYWORD NVARCHAR(200), CNT INT)
DECLARE #TABLE NVARCHAR(200)
DECLARE #TABLE_ID INT
SET #TABLE_ID = 1
DECLARE #TABLE_NAME NVARCHAR (200)
DECLARE #FOR_LOOP INT
DECLARE #COLUMN NVARCHAR(200)
DECLARE #COLUMN_NAME NVARCHAR(200)
--TOTAL NO OF RECORDS FOR LOOP
SET #FOR_LOOP = (SELECT COUNT(*)
FROM SYS.tables T
JOIN SYS.all_columns C ON T.object_id = C.object_id
JOIN INFORMATION_SCHEMA.TABLES S ON S.TABLE_NAME = T.name)
DECLARE #STRINGS NVARCHAR(200)
SET #STRINGS = '%FEC%' --------->ENTER YOUR KEYWORD HERE, TRY ONE AT A TIME
DECLARE #COUNT INT
WHILE #TABLE_ID <= #FOR_LOOP
BEGIN
SET #TABLE = (SELECT CAST(TABLE_NAME AS NVARCHAR(200))
FROM
(SELECT ROW_NUMBER()OVER(ORDER BY T.NAME) TABLE_ID
,S.TABLE_SCHEMA SCHEMA_NAME ,T.NAME TABLE_NAME, C.name COLUMN_NAME
FROM SYS.tables T
JOIN SYS.all_columns C ON T.object_id = C.object_id
JOIN INFORMATION_SCHEMA.TABLES S ON S.TABLE_NAME = T.name)A
WHERE TABLE_ID = #TABLE_ID)
SET #TABLE_NAME = '['+#TABLE+']'
SET #COLUMN = (SELECT CAST(COLUMN_NAME AS NVARCHAR(200))
FROM
(SELECT ROW_NUMBER()OVER(ORDER BY T.NAME) TABLE_ID
,S.TABLE_SCHEMA SCHEMA_NAME ,T.NAME TABLE_NAME, C.name COLUMN_NAME
FROM SYS.tables T
JOIN SYS.all_columns C ON T.object_id = C.object_id
JOIN INFORMATION_SCHEMA.TABLES S ON S.TABLE_NAME = T.name)A
WHERE TABLE_ID = #TABLE_ID)
SET #COLUMN_NAME = '['+#COLUMN+']'
DECLARE #EXEC NVARCHAR(200) = 'SELECT ' + #COLUMN_NAME +' FROM ' + #TABLE_NAME + ' WHERE ' + #COLUMN_NAME + ' LIKE ' + ''''+#STRINGS+''''
--THERE MUST BE ANOTHER WAY TO REPLACE SP_EXECUTESQL FOR BETTER PERFORMANCE, AS IT WILL BE EXECUTED AS MANY TIMES AS THERE ARE RECORDS IN #FOR_LOOP
EXEC SP_EXECUTESQL #EXEC
SET #COUNT = (SELECT ##ROWCOUNT)
IF (SELECT ##ROWCOUNT) >=1
BEGIN
INSERT INTO #TEMP VALUES
(#TABLE_NAME, #COLUMN_NAME, #STRINGS, #COUNT)
SET #TABLE_ID = #TABLE_ID + 1
END
ELSE
--DONT KNOW WHY THIS ELSE PART IS NOT TOUCHED, WHEREAS I THINK IT SHOULD HAVE
BEGIN
PRINT 'RECORD NOT FOUND'
END
END
GO
--AFTER THE ABOVE BLOCK IS EXECUTED THEN TRY RUNNING BELOW ONE
SELECT *FROM #TEMP WHERE CNT>0
--THERE MAY BE MULTIPLE ERROS, MUST BE EDITED AND CAN MAKE IT AS A PROCEDURE TOO.

SQL Cursor to use Table and Field Names from Temp Table

I'll preface this by letting you all know that I promised myself a few years ago never to use a cursor in SQL where it's not needed. Unfortunately I think I may have to use one in my current situation but it's been so long that I'm struggling to remember the correct syntax.
Basically, I've got a problem with CONVERT_IMPLICIT happening in queries because I have data types that are different for the same field in different tables so I'd like to eventually convert these to int. But to do this I need to check whether all data can be converted to int or not to see how big the job is.
I've got the query below which gives me a list of all tables in the database that contain the relevant field in a list;
IF OBJECT_ID('tempdb..#BaseData') IS NOT NULL DROP TABLE #BaseData
GO
CREATE TABLE #BaseData (Table_Name varchar(100), Field_Name varchar(100), Data_Type_Desc varchar(20), Data_Max_Length int, Convertible bit)
DECLARE #FieldName varchar(20); SET #FieldName = 'TestFieldName'
INSERT INTO #BaseData (Table_Name, Field_Name, Data_Type_Desc, Data_Max_Length)
SELECT
o.name ,c.name ,t.name ,t.max_length
FROM sys.columns c
JOIN sys.types t
ON c.user_type_id = t.user_type_id
JOIN sys.objects o
ON c.object_id = o.object_id
WHERE c.name LIKE '%' + #FieldName + '%'
AND o.type_desc = 'USER_TABLE'
Which gives results like this;
Table_Name Field_Name Data_Type_Desc Data_Max_Length Convertible
Table1 TestFieldName varchar 8000 NULL
Table2 TestFieldName nvarchar 8000 NULL
Table3 TestFieldName int 4 NULL
Table4 TestFieldName varchar 8000 NULL
Table5 TestFieldName varchar 8000 NULL
What I'd like to do is to check if all data in the relevant table & field can be converted to an int and update the 'convertible' field (1 if there's data that can't be converted, 0 if the data is fine). I've got the following calculation which works perfectly fine;
'SELECT
CASE
WHEN COUNT(' + #FieldName + ') - SUM(ISNUMERIC(' + #FieldName + ')) > 0
THEN 1
ELSE 0
END
FROM ' + #TableName
And gives the result that I'm after. But I'm struggling to get to the correct syntax to create the cursor which will look at each row in my temp table and run this SQL accordingly. It then needs to update the final column of the temp table with the result of the query (1 or 0).
This will have to be run on a couple of hundred databases which is why I need this list to be dynamic, there may well be custom tables in some databases (in fact, it's pretty likely).
If anybody could give any guidance it would be greatly appreciated.
Thanks
I made a couple of changes to your original query but here is something that should work. I have done similar things in the past :-)
Changes:
Added schema to the source table - my test database had matches in multiple schemas
Changed datatypes to sysname, smallint to match table definitions or names could get truncated
IF OBJECT_ID('tempdb..#BaseData') IS NOT NULL DROP TABLE #BaseData;
GO
CREATE TABLE #BaseData (Schema_Name sysname, Table_Name sysname, Field_Name sysname, Data_Type_Desc sysname, Data_Max_Length smallint, Convertible bit);
DECLARE #FieldName varchar(20); SET #FieldName = 'TestFieldName';
INSERT INTO #BaseData (Schema_Name, Table_Name, Field_Name, Data_Type_Desc, Data_Max_Length)
SELECT
s.name, o.name ,c.name ,t.name ,t.max_length
FROM sys.columns c
JOIN sys.types t
ON c.user_type_id = t.user_type_id
JOIN sys.objects o
ON c.object_id = o.object_id
JOIN sys.schemas s ON o.schema_id=s.schema_id
WHERE c.name LIKE '%' + #FieldName + '%'
AND o.type_desc = 'USER_TABLE';
--select * from #BaseData;
DECLARE #sName sysname,
#tName sysname,
#fName sysname,
#sql VARCHAR(MAX);
DECLARE c CURSOR LOCAL FAST_FORWARD FOR
SELECT Schema_Name,
Table_Name,
Field_Name
FROM #BaseData;
OPEN c;
FETCH NEXT FROM c INTO #sName, #tName, #fName;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = 'UPDATE #BaseData SET Convertible =
(SELECT
CASE
WHEN COUNT(' + #fName + ') - SUM(ISNUMERIC(' + #fName + ')) > 0
THEN 1
ELSE 0
END Convertible
FROM ' + #sName + '.' + #tName + ')
FROM #BaseData WHERE Schema_Name = ''' + #sName + ''' AND Table_Name = ''' + #tName + ''' AND Field_Name = ''' + #fName + '''';
--select #sql;
EXEC(#sql);
FETCH NEXT FROM c INTO #sName, #tName, #fName;
END
CLOSE c;
DEALLOCATE c;
select *
from #BaseData;
If I understand your question, I would do something like this to identify those records that do not cast as an [int].
You didn't state which version of SQL Server you're using; TRY_CAST and TRY_CONVERT are 2012 or later.
DECLARE #test AS TABLE ( [field] [sysname] );
INSERT INTO #test
( [field] )
VALUES ( N'1' ),
( N'a' );
SELECT [field]
FROM #test
WHERE TRY_CAST([field] AS [INT]) IS NULL;
-- this is the basic sql syntax for a cursor
CURSOR (https://msdn.microsoft.com/en-us/library/ms180169.aspx)
DECLARE #parameter [sysname];
BEGIN
DECLARE [field_cursor] CURSOR
FOR
SELECT [value]
FROM [<schema>].[<table>];
OPEN [field_cursor];
FETCH NEXT FROM [field_cursor] INTO #parameter;
WHILE ##FETCH_STATUS = 0
BEGIN
-- do something really interesting here
FETCH NEXT FROM [field_cursor] INTO #parameter;
END;
CLOSE [field_cursor];
DEALLOCATE [field_cursor];
END;
I wasn't able to test this but it should do what you're looking for. Just plop this in after you create your temp table:
DECLARE #tName VARCHAR(20),
#fName VARCHAR(20),
#dType VARCHAR(20),
#dLength INT,
#sql VARCHAR(MAX);
DECLARE c CURSOR LOCAL FAST_FORWARD FOR
SELECT Table_Name,
Field_Name,
Data_Type_Desc,
Data_Max_Length
FROM #BaseData;
OPEN c;
FETCH NEXT FROM c INTO #tName, #fName, #dType, #dLength;
WHILE ##FETCH_STATUS = 0
BEGIN
IF((COUNT(#FieldName) - SUM(ISNUMERIC(#FieldName))) > 0)
BEGIN
SET #sql = 'UPDATE ' + #tName + ' SET Convertible = 1 WHERE Table_Name = ''' + #tName + '''';
END
ELSE
BEGIN
SET #sql = 'UPDATE ' + #tName + ' SET Convertible = 0 WHERE Table_Name = ''' + #tName + '''';
END
EXEC(#sql);
FETCH NEXT FROM c INTO #TableName, #FieldName, #DataType, #DataLength;
END
CLOSE c;
DEALLOCATE c;

SQL Server SELECT where any column contains 'x'

Using SQL Server 2008, say I have a table called testing with 80 columns and I want to find a value called foo.
I can do:
SELECT *
FROM testing
WHERE COLNAME = 'foo'
Is it possible I can query all 80 columns and return all the results where foo is contained in any of the 80 columns?
You can use in:
SELECT *
FROM testing
WHERE 'foo' in (col1, col2, col3, . . . );
First Method(Tested)
First get list of columns in string variable separated by commas and then you can search 'foo' using that variable by use of IN
Check stored procedure below which first gets columns and then searches for string:
DECLARE #TABLE_NAME VARCHAR(128)
DECLARE #SCHEMA_NAME VARCHAR(128)
-----------------------------------------------------------------------
-- Set up the name of the table here :
SET #TABLE_NAME = 'testing'
-- Set up the name of the schema here, or just leave set to 'dbo' :
SET #SCHEMA_NAME = 'dbo'
-----------------------------------------------------------------------
DECLARE #vvc_ColumnName VARCHAR(128)
DECLARE #vvc_ColumnList VARCHAR(MAX)
IF #SCHEMA_NAME =''
BEGIN
PRINT 'Error : No schema defined!'
RETURN
END
IF NOT EXISTS (SELECT * FROM sys.tables T JOIN sys.schemas S
ON T.schema_id=S.schema_id
WHERE T.Name=#TABLE_NAME AND S.name=#SCHEMA_NAME)
BEGIN
PRINT 'Error : The table '''+#TABLE_NAME+''' in schema '''+
#SCHEMA_NAME+''' does not exist in this database!'
RETURN
END
DECLARE TableCursor CURSOR FAST_FORWARD FOR
SELECT CASE WHEN PATINDEX('% %',C.name) > 0
THEN '['+ C.name +']'
ELSE C.name
END
FROM sys.columns C
JOIN sys.tables T
ON C.object_id = T.object_id
JOIN sys.schemas S
ON S.schema_id = T.schema_id
WHERE T.name = #TABLE_NAME
AND S.name = #SCHEMA_NAME
ORDER BY column_id
SET #vvc_ColumnList=''
OPEN TableCursor
FETCH NEXT FROM TableCursor INTO #vvc_ColumnName
WHILE ##FETCH_STATUS=0
BEGIN
SET #vvc_ColumnList = #vvc_ColumnList + #vvc_ColumnName
-- get the details of the next column
FETCH NEXT FROM TableCursor INTO #vvc_ColumnName
-- add a comma if we are not at the end of the row
IF ##FETCH_STATUS=0
SET #vvc_ColumnList = #vvc_ColumnList + ','
END
CLOSE TableCursor
DEALLOCATE TableCursor
-- Now search for `foo`
SELECT *
FROM testing
WHERE 'foo' in (#vvc_ColumnList );
2nd Method
In sql server you can get object id of table then using that object id you can fetch columns. In that case it will be as below:
Step 1: First get Object Id of table
select * from sys.tables order by name
Step 2: Now get columns of your table and search in it:
select * from testing where 'foo' in (select name from sys.columns where object_id =1977058079)
Note: object_id is what you get fetch in first step for you relevant table
You can use in and you can get the column names dynamically and pass them to IN clause by making sql string and executing it using execute sp_executesql.
declare #sql nvarchar(2100)
declare #cols nvarchar(2000)
declare #toSearch nvarchar(200)
declare #tableName nvarchar(200)
set #tableName = 'tbltemp'
set #toSearch = '5'
set #cols =(
SELECT LEFT(column_name, LEN(column_name) - 1)
FROM (
SELECT column_name + ', '
FROM INFORMATION_SCHEMA.COLUMNS where table_name = #tableName
FOR XML PATH ('')
) c (column_name )
)
set #sql = 'select * from tbltemp where '''+ #toSearch + ''' in (' + #cols + ')';
execute sp_executesql #sql
I think this is one of the best ways of doing it
SELECT * FROM sys.columns a
inner join
(
SELECT object_id
FROM sys.tables
where
type='U'--user table
and name like 'testing'
) b on a.object_id=b.object_id
WHERE a.name like '%foo%'
I took the idea from ubaid ashraf's answer, but made it actually work. Just change MyTableName here:
SELECT STUFF((
SELECT ', ' + c.name
FROM sys.columns c
JOIN sys.types AS t ON c.user_type_id=t.user_type_id
WHERE t.name != 'int' AND t.name != 'bit' AND t.name !='date' AND t.name !='datetime'
AND object_id =(SELECT object_id FROM sys.tables WHERE name='MyTableName')
FOR XML PATH('')),1,2,'')
You could tweak it to your needs and add or remove conditions from the where column (the 't.name != 'int' AND t.name != 'bit' etc. part), e.g. add 't.name != 'uniqueidentifier'' to avoid getting Conversion failed when converting the varchar value 'myvalue' to data type int type of errors..
Then copy paste the result into this query (otherwise it didn't work):
SELECT * from MyTableName where 'foo' in (COPY PASTE PREVIOUS QUERY RESULT INTO HERE)
--Obtain object_id
SELECT object_id FROM sys.tables WHERE name = <your_table>
--look for desired value in specified columns using below syntax
SELECT * FROM <your_table> WHERE <VALUE_YOU_SEARCH_FOR> in
(SELECT name FROM sys.tables WHERE object_id = <your_table_object_id>
and name like '<if_you_have_multiple_columns_with_same_name_pattern>')
I've worked with BornToCode's answer and this script generates the queries to find a value in all columns of type varchar for any view (can be table) of the database:
DECLARE #id INT
declare #name nvarchar(30)
DECLARE #getid CURSOR
declare #value nvarchar(30)
set #value = 'x'
SET #getid = CURSOR FOR
SELECT object_id,name
FROM sys.views
OPEN #getid
FETCH NEXT
FROM #getid INTO #id, #name
WHILE ##FETCH_STATUS = 0
BEGIN
---------
SELECT 'SELECT * from ' + #name + ' where ''' + #value + ''' in (' +
STUFF((
SELECT ', ' + c.name
FROM sys.columns c
JOIN sys.types AS t ON c.user_type_id=t.user_type_id
WHERE t.name = 'varchar'-- AND t.name != 'bit' AND t.name !='date' AND t.name !='datetime'
AND object_id =(SELECT object_id FROM sys.views WHERE name=#name)
FOR XML PATH('')),1,2,'')
+ ')' as 'query'
------
FETCH NEXT
FROM #getid INTO #id, #name
END
CLOSE #getid
DEALLOCATE #getid

List all columns referenced in all procedures of all databases

Is there a way that I can get all the columns and tables referenced in all the stored procedures in all the databases in an instance? The output should be:
Database Procedure Table Column
-------- --------- ----- ------
This will get the list you're after, however it won't help you if you have such column references embedded in dynamic SQL (and may not find references that rely on deferred name resolution). SQL Server doesn't parse the text of the stored procedure to come up with the DMV output.
Try now with COLLATE clauses to deal with cases where you have databases on the same server with different collations.
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql += N'UNION ALL
SELECT
[database] = ''' + REPLACE(name, '''', '''''') + ''',
[procedure] = QUOTENAME(s.name) + ''.'' + QUOTENAME(p.name)
COLLATE Latin1_General_CI_AI,
[table] = QUOTENAME(referenced_schema_name) + ''.''
+ QUOTENAME(referenced_entity_name)
COLLATE Latin1_General_CI_AI,
[column] = QUOTENAME(referenced_minor_name)
COLLATE Latin1_General_CI_AI
FROM ' + QUOTENAME(name) + '.sys.schemas AS s
INNER JOIN ' + QUOTENAME(name) + '.sys.procedures AS p
ON s.[schema_id] = p.[schema_id]
CROSS APPLY ' + QUOTENAME(name)
+ '.sys.dm_sql_referenced_entities'
+ '(QUOTENAME(s.name) + ''.'' + QUOTENAME(p.name), N''OBJECT'') AS d
WHERE d.referenced_minor_id > 0'
FROM sys.databases
WHERE database_id > 4
AND [state] = 0;
SET #sql = STUFF(#sql,1,11,'');
EXEC sp_executesql #sql;
Also the CROSS APPLY syntax won't work if you have databases that are in 80 compatibility mode. Just make sure you don't execute the code in such a database and it should work fine (even if some of the target databases are in 80).
To list all SP Name have contain the specified column name:
SELECT OBJECT_NAME(M.object_id), M.*
FROM sys.sql_modules M
JOIN sys.procedures P
ON M.object_id = P.object_id
WHERE M.definition LIKE '%ColumnName%'
Here is yet another way to do this. This is very DIRTY but I like it. Why? Because I came up with it. Anyway it is using Dynamic SQL inside Dynamic SQL to insert dependency information into temp table that can be queried.
This can be modified into a SP that you can run from time to time to update dependencies information, also temp table can be changes to real table if you want to store it.
IF OBJECT_ID('tempdb.dbo.#SPDependencyDetails') IS NOT NULL
DROP TABLE #SPDependencyDetails
CREATE TABLE #SPDependencyDetails
(
Or_Object_Database NVARCHAR(128)
,Or_Object_Name NVARCHAR(128)
,Ref_Database_Name NVARCHAR(128)
,Ref_Schema_Name NVARCHAR(128)
,Ref_Object_Name NVARCHAR(128)
,Ref_Column_Name NVARCHAR(128)
,Is_Selected BIT
,Is_Updated BIT
,Is_Select_All BIT
,Is_All_Columns_Found BIT
)
DECLARE #database_name VARCHAR(100)
DECLARE database_cursor CURSOR
FOR
SELECT name
FROM sys.databases
WHERE database_id > 4
OPEN database_cursor
FETCH NEXT FROM database_cursor
INTO #database_name
WHILE ##FETCH_STATUS = 0 --Outer Loop begin
BEGIN
DECLARE #WholeLotofSQL NVARCHAR(MAX) = '
DECLARE #object_name VARCHAR(150)
,#sqlstatement NVARCHAR(2500)
DECLARE object_cursor CURSOR --Inner cursor, iterates list of objects that match type
FOR
SELECT name
FROM '+#database_name+'.sys.objects AS o
WHERE o.type = ''P'' --Change Object type to find dependencies of Functions, Views and etc.
ORDER BY 1
OPEN object_cursor
FETCH NEXT FROM object_cursor INTO #object_name
WHILE ##FETCH_STATUS = 0 --Inner Loop Begin
BEGIN
SET #sqlstatement = ''USE '+#database_name+';
INSERT INTO #SPDependencyDetails
SELECT DB_NAME() AS Or_Object_Database
,'''''' + #object_name + '''''' AS Or_Object_Name
,CASE WHEN referenced_database_name IS NULL THEN DB_NAME()
ELSE referenced_database_name
END AS Ref_Database_Name
,referenced_schema_name AS Ref_Schema_Name
,referenced_entity_name AS Ref_Object_Name
,referenced_minor_name AS Ref_Column_Name
,is_selected
,is_updated
,is_select_all
,is_all_columns_found
FROM sys.dm_sql_referenced_entities(''''dbo.'' + #object_name + '''''', ''''OBJECT'''');''
EXEC sys.sp_executesql #sqlstatement
FETCH NEXT FROM object_cursor INTO #object_name
END
CLOSE object_cursor
DEALLOCATE object_cursor'
EXEC sys.sp_executesql #WholeLotofSQL
FETCH NEXT FROM database_cursor INTO #database_name
END
CLOSE database_cursor;
DEALLOCATE database_cursor;
SELECT Or_Object_Database as 'Database'
,Or_Object_Name as 'Procedure'
,Ref_Object_Name as 'Table'
,Ref_Column_Name as 'Column
FROM #SPDependencyDetails