Searching for data in all existing tables of a database - sql

I want to search for the date '2017-08-08 09:26' in all existing tables of a database and get the column name and table name of the table that contains that date. So I can find that date in table A in column a.
example: '2017-08-08 09:26' exists in column 'a' of table 'A'
Please give me some suggestions for a solution.
Right now I am using this query in which I can search for columns, but I want to search the data in the columns of the tables in my database.
SELECT
sys.columns.name AS ColumnName,
sys.tables.name AS TableName
FROM
sys.columns
JOIN
sys.tables
ON
sys.columns.object_id = sys.tables.object_id
WHERE
sys.columns.name LIKE '%service%'

You need some good old-fashion dynamic SQL for this:
DECLARE #Sql varchar(max);
SELECT #Sql = STUFF((SELECT 'UNION ALL ' + CHAR(10) +'SELECT '''+
sys.columns.name +''' AS ColumnName, '''+
sys.tables.name +''' AS TableName '+ CHAR(10) +
'FROM sys.tables.name ' + CHAR(10) +
'WHERE '+ QUOTENAME(sys.columns.name) +' = #DateTimeValue ' + CHAR(10)
FROM
sys.columns
JOIN
sys.tables
ON
sys.columns.object_id = sys.tables.object_id
-- type ids: datetime2, smalldatetime, datetime
WHERE sys.columns.system_type_id IN(42, 58, 61)
FOR XML PATH('')
), 1, 11, 'DECLARE #DateTimeValue datetime = ''2017-08-08T09:26:00'';' + CHAR(10))
-- When using dynamic SQL, PRINT is your best friend.
PRINT #Sql
/*
#Sql should contain something like this:
DECLARE #DateTimeValue datetime = '2017-08-08T09:26:00';
SELECT 'Col1' AS ColumnName, 'Table1' AS TableName
FROM sys.tables.name
WHERE [Col1] = #DateTimeValue
UNION ALL
SELECT 'Col2' AS ColumnName, 'Table12' AS TableName
FROM sys.tables.name
WHERE [Col2] = #DateTimeValue
...
*/
-- Unremark only after you've seen what's inside #Sql.
--EXEC(#Sql)

Use the below script for getting entire DB search
DECLARE
#SearchStr nvarchar(100) = 'Pass'
BEGIN
DECLARE #Results TABLE(ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256), #ColumnName nvarchar(128), #SearchStr2 varchar(110)
SET #TableName = ''
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%','''')
WHILE #TableName IS NOT NULL
BEGIN
SET #ColumnName = ''
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (#TableName IS NOT NULL) AND (#ColumnName IS NOT NULL)
BEGIN
SET #ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(#TableName, 2)
AND TABLE_NAME = PARSENAME(#TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > #ColumnName
)
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
END

Related

Search all tables for multiple values

The below beautiful SP returns the table and columnname and the value
What I am interested in however is to do this search for multiple values.
The only thing I want to know is a distinct output of the table/columnname not the value.
So basically I want to know all tables / columnnames in which my values exist
Then from there I can make a dynamic update query to rename these values in the existing columns ()
So searching these values by making a join maybe would be better.
I also already thought of stacking the entire database in one giant table in which I can then join on a like. But it's a bit of a headache.. any suggestions?
CREATE PROC SearchAllTables
(
#SearchStr nvarchar(100)
)
AS
BEGIN
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256), #ColumnName nvarchar(128), #SearchStr2 nvarchar(110)
SET #TableName = ''
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%','''')
WHILE #TableName IS NOT NULL
BEGIN
SET #ColumnName = ''
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (#TableName IS NOT NULL) AND (#ColumnName IS NOT NULL)
BEGIN
SET #ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(#TableName, 2)
AND TABLE_NAME = PARSENAME(#TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
AND QUOTENAME(COLUMN_NAME) > #ColumnName
)
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results END
It depends on what version of SQL Server you are using and the functionality that exists for parsing text. I mainly use SQL Server 2005 so I am pretty limited, but you can parse #SearchStr and put the values into a temp table and then use that to join back to.
DECLARE #SearchStr nvarchar(100)
SET #SearchStr = N'123|456|789|ABC|DEF|GHI'
IF OBJECT_ID(N'tempdb..#SearchStrings') IS NOT NULL DROP TABLE #SearchStrings
CREATE TABLE #SearchStrings (ID INT IDENTITY, SearchString NVARCHAR(100))
WHILE #SearchStr <> ''
BEGIN
INSERT INTO #SearchStrings (SearchString) SELECT CASE WHEN #SearchStr LIKE N'%|%' THEN LEFT(#SearchStr, CHARINDEX('|', #SearchStr) - 1) ELSE #SearchStr END
SET #SearchStr = STUFF(#SearchStr, 1, CASE WHEN #SearchStr LIKE N'%|%' THEN CHARINDEX('|', #SearchStr) ELSE LEN(#SearchStr) END, N'')
END
SELECT * FROM #SearchStrings
Or you can just parse the values and use them directly.
DECLARE #SearchStr nvarchar(100)
SET #SearchStr = N'123|456|789|ABC|DEF|GHI'
WHILE #SearchStr <> ''
BEGIN
PRINT CASE WHEN #SearchStr LIKE N'%|%' THEN LEFT(#SearchStr, CHARINDEX('|', #SearchStr) - 1) ELSE #SearchStr END
SET #SearchStr = STUFF(#SearchStr, 1, CASE WHEN #SearchStr LIKE N'%|%' THEN CHARINDEX('|', #SearchStr) ELSE LEN(#SearchStr) END, N'')
END
I think I've got it, the purpose was to find all tables in which my values exists and then based on that create multiple update statements to for example add a prefix to the original values, I ended up doing what I suggested that is to stuff the entire database into 2 columns and join on those columns (compared to looping through this query for each value, this happened to be much faster) :
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
alter PROC [dbo].[SearchAllTables]
(
#SearchStr nvarchar(100)
)
AS
BEGIN
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256), #ColumnName nvarchar(128), #SearchStr2 nvarchar(110)
SET #TableName = ''
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%','''')
WHILE #TableName IS NOT NULL
BEGIN
SET #ColumnName = ''
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
AND TABLE_CATALOG = 'TPV_BE_PRD'
)
WHILE (#TableName IS NOT NULL) AND (#ColumnName IS NOT NULL)
BEGIN
SET #ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(#TableName, 2)
AND TABLE_NAME = PARSENAME(#TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > #ColumnName
)
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) '
)
END
END
END
SELECT distinct ColumnName FROM #Results a inner join OITM b on a.ColumnValue = b."ItemCode" COLLATE SQL_Latin1_General_CP850_CI_AS END

loop throgh all the data to search particular string [duplicate]

This question already has answers here:
Find a value anywhere in a database
(18 answers)
Closed 5 years ago.
I want to loop throgh all the column of all the tables available in my database to check which column containts string "Kroki Homes".
I have approx. 56 tables in my database. So it is hard to check in all the columns of these 56 tables. is there any easy way to achieve this in sql server?
You can create one procedure and can pass the string for search. I found this some where this might help you.
CREATE PROC [dbo].[SearchDataFromAllTables] (#SearchStr NVARCHAR(100))
AS
BEGIN
SET NOCOUNT ON;
CREATE TABLE #Results
(
ColumnName NVARCHAR(370),
ColumnValue NVARCHAR(3630)
)
DECLARE #TableName NVARCHAR(256)
, #ColumnName NVARCHAR(128)
, #SearchStr2 NVARCHAR(110)
SET #TableName = ''
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%', '''')
WHILE #TableName IS NOT NULL
BEGIN
SET #ColumnName = ''
SET #TableName = (
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0
)
WHILE (#TableName IS NOT NULL)
AND (#ColumnName IS NOT NULL)
BEGIN
SET #ColumnName = (
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(#TableName, 2)
AND TABLE_NAME = PARSENAME(#TableName, 1)
AND DATA_TYPE IN (
'char'
,'varchar'
,'nchar'
,'nvarchar'
)
AND QUOTENAME(COLUMN_NAME) > #ColumnName
)
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC (
'SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' + ' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
END
You need to write a stored procedure to scan through all the tables.
The script below gives to the tables and columns. From this you should create a SQL in-flight and execute dynamically to SELECT from tables. Let us know if you need more details.
SELECT tb.name AS table_name,
c.name AS column_name,
c.column_id,
tp.name AS column_data_type,
c.max_length,
c.precision,
c.scale,
CASE c.is_nullable WHEN 1 THEN 'YES' ELSE 'NO' END AS is_nullable
FROM sys.tables tb,
sys.columns c,
sys.types tp
WHERE tb.object_id = c.object_id
AND SCHEMA_NAME(tb.schema_id) = 'dbo'
AND c.user_type_id = tp.user_type_id
ORDER BY table_name, column_id;

Get all tables having Value in SQL Server [duplicate]

This question already has answers here:
Find a value anywhere in a database
(18 answers)
Closed 8 years ago.
I need to find a value wherever present in database.
Consider I need to find value "Fish" from Database.
Output I need is
Table Name | Column Name
--------------------------
Table 1 | columnName
Table 12 | columnName
and so on..
try this,
Declare #SearchStr nvarchar(100) = 'YorValue' -- Here type your text
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256), #ColumnName nvarchar(128), #SearchStr2 nvarchar(110)
SET #TableName = ''
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%','''')
WHILE #TableName IS NOT NULL
BEGIN
SET #ColumnName = ''
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (#TableName IS NOT NULL) AND (#ColumnName IS NOT NULL)
BEGIN
SET #ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(#TableName, 2)
AND TABLE_NAME = PARSENAME(#TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > #ColumnName
)
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
drop table #Results
This query may help you
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE 'your column name'
ORDER BY schema_name, table_name;

How to find which column in a table in a database has an '!' exclamation mark.

Say I have a table 'Tablex' in a database DB1, with diff columns column1, column2, ...etc columnx one of these columns has data with an exclamation mark say for example 'Durian!Tex'
what is the query to find which table in which db has a column which contains a value '%!%'
This is to search the whole database to give out the Db name, Table Name, column name . Hope My question is clear.
export the whole database to .sql file and find it by using cntrl+F
And replace/remove it whatever you want
and import it to the new database
I have found one store procedure from the internet when i was looking for same thing. You can use following SP to find text/Character in all the columns in the tables.
First run the SP and then execute the sp using EXEC and search the character in parameter value.
--EXEC SearchAllTables '!'
CREATE PROC SearchAllTables
(
#SearchStr nvarchar(100)
)
AS
BEGIN
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256), #ColumnName nvarchar(128), #SearchStr2 nvarchar(110)
SET #TableName = ''
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%','''')
WHILE #TableName IS NOT NULL
BEGIN
SET #ColumnName = ''
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (#TableName IS NOT NULL) AND (#ColumnName IS NOT NULL)
BEGIN
SET #ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(#TableName, 2)
AND TABLE_NAME = PARSENAME(#TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > #ColumnName
)
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
END
Hope this will help you.

How to write SQL script to find rows in any tables of a SQL Server database that have a string column which value is equal to a keyword?

Environment: Windows, SQL Server 2008
For example, my database has Table1, Table2, Table3... TableN, each table has Column1, Column2, Column3...ColumnN. Simply, they're all string column.
I want to find rows, no matter from which table, which have a column's value is 'Key' no matter which column.
How to write a script to do that?
Thanks!
Take a look at the FindMyData_String stored proc here: Search all columns in all the tables in a database for a specific value to get you started
CREATE PROC SearchAllTables
(
#SearchStr nvarchar(100)
)
AS
BEGIN
DECLARE #SearchStr nvarchar(100)
SET #SearchStr = 'Wound'
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256), #ColumnName nvarchar(128), #SearchStr2 nvarchar(110)
SET #TableName = ''
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%','''')
WHILE #TableName IS NOT NULL
BEGIN
SET #ColumnName = ''
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (#TableName IS NOT NULL) AND (#ColumnName IS NOT NULL)
BEGIN
SET #ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(#TableName, 2)
AND TABLE_NAME = PARSENAME(#TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > #ColumnName
)
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
END
try this, but this will only work on similar structured table
DECLARE #Table nvarchar(100), #Column nvarchar(100)
DECLARE #SQLStringBuilder nvarchar(MAX) = ''
DECLARE MY_CURSOR Cursor
FOR SELECT sysobjects.name, syscolumns.name
FROM sysobjects
JOIN syscolumns ON sysobjects.id = syscolumns.id
JOIN systypes ON syscolumns.xtype=systypes.xtype
WHERE sysobjects.xtype='U' and systypes.name <> 'sysname' and systypes.name = 'nvarchar'
ORDER BY sysobjects.name,syscolumns.colid
Open MY_CURSOR
Fetch NEXT FROM MY_CURSOR INTO #Table, #Column
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQLStringBuilder = #SQLStringBuilder + ' SELECT ''' + #Table + ''' as TableName, ''' + #Column + ''' as ColumnName, * FROM ' + #Table + ' WHERE ' + #Column+ ' = ''Key'' UNION ALL'
Fetch NEXT FROM MY_CURSOR INTO #Table, #Column
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
SET #SQLStringBuilder = SUBSTRING(#SQLStringBuilder, 0, LEN(#SQLStringBuilder)-9)
EXEC(#SQLStringBuilder)