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
Related
need to implement server side Search functionality
My requirement is as follows:
The string inserted in the textbox has to checked in every column-data in the database. if it matches or the string is contained by any of the column-data in the database that row is valid for displaying.
There is a pagination part too, that is also handled in the DB and the stored procedure has to send only an specified no of rows calculated based on the pageIndex, and rowCount passed to the stored Procedure, this calculation also is happening in the stored procedure only.
In the Stored procedure we are pulling the data from Different table using joins and pushing it to a temporary table, and finally the data from the temporary table is sent back.
Here my problem is I am not able to use the Contains() method for searching the pattern so what should be the approach to wards this functionality. so that this can be done efficiently??
thanks
Check following query. You need to replace test with the value you want to search. This will give Column name and value of matching string. I hope this will help you to find your answer.
Declare #SearchStr nvarchar(100)
set #SearchStr='test'
DECLARE #Results TABLE (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`
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.
I have DB which contains more than 100 tables. Most of the tables have names like SY0001234 I know data which stored in that table but do not know the name of it so cant run normal select against it. Do you have any ideas how to find the table name?
You do perform something like this
--EXEC SearchAllTables 'test'
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
You may do better to read this article - http://www.sqlservercentral.com/articles/T-SQL/67624/
I realize I am late to the party - but this may help you.
I have a huge schema, with several hundreds of tables and several thousands of columns. I'd know that a specific IP address is stored in this database in several places, but I'm not sure what table(s) or column(s) it is stored in. Basically, I'm trying to find everywhere that this IP address is stored in the DB so I can update it to a new value in all those places.
Here's my first crack at a T-SQL statement to print out the table and column name, and the value, for every text column in the database that has the substring 10.15.13 in it.
Now, this works, sort of. The problem is, when I execute it in Management Studio, the call to sp_executesql will actually return all the empty results from every query that returns nothing (i.e. the column doesn't have any records with that substring), and it fills the result window to its max, and then I don't actually see if anything was printed.
Is there a better way to write this query? Or can I run it in some different way so that it only shows me the Tables and Columns where this substring exists?
DECLARE
#SchemaName VARCHAR(50),
#TableName VARCHAR(50),
#ColumnName VARCHAR(50);
BEGIN
DECLARE textColumns CURSOR FOR
SELECT s.Name, tab.Name, c.Name
FROM Sys.Columns c, Sys.Types t, Sys.Tables tab, Sys.Schemas s
WHERE s.schema_id = tab.schema_id AND tab.object_id = c.object_id AND c.user_type_id = t.user_type_id
AND t.Name in ('TEXT','NTEXT','VARCHAR','CHAR','NVARCHAR','NCHAR');
OPEN textColumns
FETCH NEXT FROM textColumns
INTO #SchemaName, #TableName, #ColumnName
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #sql NVARCHAR(MAX),
#ParamDef NVARCHAR(MAX),
#result NVARCHAR(MAX);
SET #sql = N'SELECT ' + #ColumnName + ' FROM ' + #SchemaName + '.' + #TableName + ' WHERE ' + #ColumnName + ' LIKE ''%10.15.13%''';
SET #ParamDef = N'#resultOut NVARCHAR(MAX) OUTPUT';
EXEC sp_executesql #sql, #ParamDef, #resultOut = #result OUTPUT;
PRINT 'Column = ' + #TableName + '.' + #ColumnName + ', Value = ' + #result;
FETCH NEXT FROM textColumns
INTO #SchemaName, #TableName, #ColumnName
END
CLOSE textColumns;
DEALLOCATE textColumns;
END
I'd like to see results something like this where it shows the table/column that the substring was found in, and the full value in that column...
Column = SomeTable.SomeTextColumn, Value = 'https://10.15.13.210/foo'
Column = SomeTable.SomeOtherColumn, Value = '10.15.13.210'
etc.
You'r close. Compare yours with this example: Searching and finding a string value in all columns in a SQL Server table
The above link is for searching a single table, however here is another link which includes all tables: How to search all columns of all tables in a database for a keyword?
EDIT : Just in case the link ever goes bad, here's the solution from that link...
CREATE PROC SearchAllTables
(
#SearchStr nvarchar(100)
)
AS
BEGIN
-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved.
-- Purpose: To search all columns of all tables for a given search string
-- Written by: Narayana Vyas Kondreddi
-- Site: http://vyaskn.tripod.com
-- Tested on: SQL Server 7.0 and SQL Server 2000
-- Date modified: 28th July 2002 22:50 GMT
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
EXEC SearchAllTables '<yourSubstringHere>'
Note:
As the comment suggests in the code snippet, it was tested using older versions of SQL Server. This may not work on SQL Server 2012.
The chosen answer is brilliant, but I found when using it repeatedly the results were erroneous, so I added some clean up to make it re-runnable with accurate results:
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'SearchAllTables')
DROP PROC SearchAllTables
GO
CREATE PROC SearchAllTables
(
#SearchStr nvarchar(100)
)
AS
BEGIN
-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved.
-- Purpose: To search all columns of all tables for a given search string
-- Written by: Narayana Vyas Kondreddi
-- Slightly modified by: Natalie Ford, 6/10/15
-- Site: http://vyaskn.tripod.com
-- Tested on: SQL Server 7.0 and SQL Server 2000
-- Date modified: 28th July 2002 22:50 GMT
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
TRUNCATE Table #Results
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
END
try this It will not give you the error of limit exceed 32
alter 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 it helps
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)