I'm trying to create a stored procedure that will search all user created tables of a database for a search string.
I found this stored procedure that I'd like to start off with and build on.
http://vyaskn.tripod.com/search_all_columns_in_all_tables.htm
The only problem is entering a datetime into the search will always return nothing.
How can I modify this to search for dates as well?
Lines of interest:
CREATE PROC SearchAllTables
#SearchStr nvarchar(100)
AS
....
SET #SearchStr2 = CASE WHEN ISDATE(#SearchStr)=0
THEN QUOTENAME('%' + #SearchStr + '%','''')
ELSE #SearchStr END
....
--Here's where the comparison is made. This comparison works for string and numeric types but not datetime
DECLARE #sql nvarchar(max)
IF ISDATE(#SearchStr) = 0
BEGIN
SET #sql = 'INSERT INTO #Results SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
END
ELSE IF ISDATE(#SearchStr) = 1
BEGIN
SET #sql = 'INSERT INTO #Results SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE DATEDIFF(day, CONVERT(datetime, '+ #ColumnName + ', 103), ' + #SearchStr+ ') = 0'
END
PRINT #sql
EXEC sp_ExecuteSQL #sql
GO
I get a conversion error. I need this stored procedure to work with all 3 types of data string, numeric, and date.
Conversion failed when converting date and/or time from character string.
Thank you
your date field is a datetime?
you should traet it like this:
declare #SearchStr datetime
set #SearchStr = convert(datetime, '2012-09-10', 103) –- dd/mm/yyyy
and the where part like this:
'WHERE Datediff(day, CONVERT(datetime, '+ #ColumnName + ', 103), ' + #SearchStr+') = 0'
I think this should work
If the search string is a date then you have to do an explicit conversion. Otherwise string will not match with datetime.
Try something like this.
SET #SearchStr2 = CASE WHEN ISDATE(#SearchStr)=1
THEN CONVERT(datetime,#SearchStr,103)
ELSE QUOTENAME('%' + #SearchStr + '%','''') END
Hope this will help you.
ElVieejo's answer was correct but for it to finally work I also needed to SET #ColumnName conditionally (depending IF ISDATE(#SearchStr) ). If #SearchStr is a date, the inner query of SET #ColumnName had to EXCLUDE all types except the 'datetime' under "DATA_TYPE IN ('datetime')".
Related
This is a progression from the question asked here: How to SELECT and UNION from a group of Tables in the schema in SQL Server 2008 R2
I would like to do very much the same thing and the answer given by MarkD works perfectly for the database I am currently working with. Although admittedly I'd like to understand exactly how. How does the query below build the union query from the list of tables returned by the information_schema?
DECLARE #Select_Clause varchar(600) = N'SELECT [Patient_Number] AS [ID number]
,[Attendance Date] AS [Date Seen]
,[Attendance_Type] AS [New/Follow up]
,[Episode Type] AS [Patient Type]
,[Local Authority District]
,Postcode, N''Shaw'' AS Clinic '
,#Where_Clause varchar(100) = N' WHERE [EPISODE TYPE] LIKE N''HIV'''
,#Union_Clause varchar(100) = N' UNION ALL '
,#Query nvarchar(max) = N''
,#RawDataBase varchar(50) = N'BHT_1819_RawData'
,#Schema varchar(50) = N'HIVGUM'
,#Table_Count tinyint;
DECLARE #Table_Count_def nvarchar(100) = N'#TableSchema varchar(50)
,#Table_CountOUT tinyint OUTPUT'
,#Start_Position int = LEN(REPLACE(#Select_Clause, N' ', N'-'))
,#Length int;
SET #Query = N'SELECT #Table_CountOUT = COUNT(*) FROM ' + #RawDataBase +
N'.INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA LIKE #TableSchema';
EXEC sp_executesql #query, #Table_Count_def, #TableSchema=#Schema,
#Table_CountOUT=#Table_Count OUTPUT;
SET #Query = N'';
IF #Table_Count > 0
Begin
IF OBJECT_ID(N'dbo.HIV_Cumulative', N'U') is not null
DROP TABLE dbo.HIV_Cumulative;
SELECT #Query = #Query + #Select_Clause + N' FROM ' + #RawDataBase +
N'.HIVGUM.' + TABLE_NAME + #Where_Clause + #Union_Clause
FROM BHT_1819_RawData.INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA LIKE #Schema;
SET #Length = LEN(REPLACE(#query, N' ', N'-')) - #Start_Position -
LEN(REPLACE(#Where_Clause + #Union_Clause, N' ', N'-'));
SELECT #Query = SUBSTRING(#QUERY , #Start_Position+1, #Length)
SET #Query = #Select_Clause + N' INTO BHT_SLR..HIV_Cumulative ' + #QUERY
+ #Where_Clause;
EXEC sp_executesql #Query
End
ELSE
PRINT N'No tables present in database ' + #RawDataBase + N' for Schema ' +
#Schema + N'. You must import source data first.';
The added complication is that I am querying the tables on a separate DB - currently BHT_1819_RawData - so have hard coded the database where it queries the information_schema. What I would really like to do is to specify the separate database using a variable. So that it can be reconfigured to extract from BHT_1920_RawData. I am fairly familiar with exec and sp_executesql, but have only occasionally used output parameters so am not sure what is required here. The attempts that I have made haven't worked. Once I have got this right, I will need to create several other similar scripts that work on the same principle.
Once I realised what needed to happen, I went through some trial and error and came up with a solution:
SET #ParmDef = N'#QueryOut nvarchar(2500) OUTPUT';
SET #sql_string = N'SELECT #QueryOut = #QueryOut + N'''
+ #Select_Clause + ' FROM '
+ #RawDataBase
+ N'.[' + #Schema + N'].'' + TABLE_NAME + N'' '
+ #Where_Clause
+ #Union_Clause
+ N''' FROM '
+ #RawDataBase
+ N'.INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA LIKE '''
+ #Schema
+ N''' AND TABLE_NAME NOT LIKE N''%_YTD%''';
EXEC sp_executesql #sql_string, #ParmDef, #QueryOut=#Query OUTPUT;
SET #Length = LEN(REPLACE(#query, N' ', N'-')) - #Start_Position -
LEN(REPLACE(#Where_Clause + #Union_Clause, N' ', N'-'));
SELECT #Query = SUBSTRING(#QUERY , #Start_Position, #Length+1);
SET #Query = REPLACE(#Select_Clause, N'''''', '''') + N' INTO ' + #New_Table + N' ' +
#QUERY + REPLACE(#Where_Clause, N'''''', '''');
EXEC sp_executesql #Query;
I am currently working on an SQL Server 2005, and trying to structure a dynamic query as follows:
DECLARE #GETDATE AS NVARCHAR(12);
DECLARE #GETDATE2 AS NVARCHAR(12);
SET #GETDATE = ...;
SET #GETDATE2 = ...;
SET #SQL =
'CREATE TABLE [dbo].[' + #TABLENAME + ']'
+'('
+'ShibNo' 'INT'
+')'
+';'
+ CHAR(10)
+'INSERT INTO [dbo].[' + #TABLENAME + '] (ShibNo)'
+'SELECT X.[ShibNo]'
+'FROM'
+'('
+'SELECT'
+ 'I.[Shibno]'
+',' + 'I.[ShibAzmnDate]'
+',' + 'I.[ShibBeginTime]'
+',' + 'I.[ShibEndTime]'
+',' + 'I.[CarNum]'
+',' + 'I.[DriverNo1]'
+',' + 'I.[ShibKind]'
+',' + 'I.[FStationID]'
+',' + 'I.[LStationID]'
+',' + 'I.[LineDetailRecordID]'
+'FROM Inserted2 I'
+'WHERE I.[ShibAzmnDate] BETWEEN ' + #GETDATE + ' AND ' + #GETDATE2 +
+'INTERCEPT'
+'SELECT'
+ 'D.[Shibno]'
+',' + 'D.[ShibAzmnDate]'
+',' + 'D.[ShibBeginTime]'
+',' + 'D.[ShibEndTime]'
+',' + 'D.[CarNum]'
+',' + 'D.[DriverNo1]'
+',' + 'D.[ShibKind]'
+',' + 'D.[FStationID]'
+',' + 'D.[LStationID]'
+',' + 'D.[LineDetailRecordID]'
+'FROM Deleted2 D'
+'WHERE D.[ShibAzmnDate] BETWEEN ' + #GETDATE + ' AND ' + #GETDATE2 +
+') AS X'
+';'
;
EXECUTE sp_executesql #SQL
;
As you can see, there are parameters in the WHERE clauses of the query string which are meant to restrict the date range of the checks performed here. However, when the string is executed as a query using sp_executesql, the dates don't receive the proper apostrophe punctuation, which creates errors.
I have tried using replace and escaping the characters, but apparently do not know the proper way to do this. I would be very happy (and grateful!) to learn how to do this correctly.
The string returned if I check the build-up of the query is one of the following variations:
' WHERE D.[ShibAzmnDate] BETWEEN ''03/13/2016'' AND ''03/14/2016'' '
OR
' WHERE D.[ShibAzmnDate] BETWEEN 03/13/2016 AND 03/14/2016 '
OR
' WHERE D.[ShibAzmnDate] BETWEEN ''''03/13/2016'''' AND ''''03/14/2016'''' '
and so on...
Can someone please help me to understand how to properly structure this dynamic query string (and future dynamic query strings) to avoid this issue?
Many, many thanks in advance!
Use parameter placeholders in the query, and then pass the values of the parameters to sp_executesql. See https://msdn.microsoft.com/en-us/library/ms188001.aspx for more details.
DECLARE #GETDATE AS NVARCHAR(12);
DECLARE #GETDATE2 AS NVARCHAR(12);
SET #GETDATE = ...;
SET #GETDATE2 = ...;
SET #SQL =
'CREATE TABLE [dbo].[' + #TABLENAME + ']'
+'('
+'ShibNo' 'INT'
+')'
+';'
+ CHAR(10)
+'INSERT INTO [dbo].[' + #TABLENAME + '] (ShibNo)'
+'SELECT X.[ShibNo]'
+'FROM'
+'('
+'SELECT'
+ 'I.[Shibno]'
. . .
+'FROM Inserted2 I'
+'WHERE I.[ShibAzmnDate] BETWEEN #StartDate AND #EndDate'
+'INTERCEPT'
+'SELECT'
+ 'D.[Shibno]'
. . .
+'FROM Deleted2 D'
+'WHERE D.[ShibAzmnDate] BETWEEN #StartDate AND #EndDate'
+') AS X'
+';'
;
EXECUTE sp_executesql #SQL, N'#StartDate DATE, #EndDate DATE',
#StartDate = #GETDATE, #EndDate = #GETDATE2
;
Try it is working for me.
DECLARE #DATE VARCHAR(250) = '2016-01-01', #VAR VARCHAR(MAX)
SELECT #VAR = 'SELECT * FROM TABLE_A WHERE CREATE_DTE> '''+#DATE+''''
SELECT #VAR
1 MSSQL supports multiline string literals so you don't have to concat each line separately (don't quite understand why are you concatenating comma as a separate litera)
2 Since you are using sp_executesql and have variables of appropriate type you don't need them in sql text and don't have to convert them to varchar
SET #SQL =
cast('CREATE TABLE [dbo].[' as nvarchar(max)) + #TABLENAME + ']
(
ShibNo INT
);
INSERT INTO [dbo].[' + #TABLENAME + '] (ShibNo)
SELECT X.[ShibNo]
FROM
(
SELECT
I.[Shibno]
,I.[ShibAzmnDate]
,I.[ShibBeginTime]
,I.[ShibEndTime]
,I.[CarNum]
,I.[DriverNo1]
,I.[ShibKind]
,I.[FStationID]
,I.[LStationID]
,I.[LineDetailRecordID]
FROM Inserted2 I
WHERE I.[ShibAzmnDate] BETWEEN #date1 AND #date2
INTERCEPT
SELECT
D.[Shibno]
,D.[ShibAzmnDate]
,D.[ShibBeginTime]
,D.[ShibEndTime]
,D.[CarNum]
,D.[DriverNo1]
,D.[ShibKind]
,D.[FStationID]
,D.[LStationID]
,D.[LineDetailRecordID]
FROM Deleted2 D
WHERE D.[ShibAzmnDate] BETWEEN #date1 AND #date2
) AS X'
EXECUTE sp_executesql #SQL, N'#date1 datetime, #date2 datetime', #getdate, #getdate2;
I'm new to SQLServer scripting (normally being a C++ developer), and would really appreciate a bit of assistance.
I am attempting to perform a "find and replace" update on all tables in a SQLServer database that contain a 'PROJID' column. I am really struggling to find a way to do this that doesn't report to me:
Msg 207, Level 16, State 1, Line 1 Invalid column name 'PROJID'.
The statement I am executing is:
EXEC
(
'IF EXISTS(SELECT * FROM sys.columns WHERE name = N''PROJID'' AND Object_ID = Object_ID(N''' + #TableName + '''))' +
' BEGIN' +
' UPDATE ' + #TableName +
' SET ' + #ColumnName + ' = REPLACE(' + #ColumnName + ',''' + #ReplaceIDStr + ''',''' + #FindIDStr + ''')' +
' WHERE ' + #ColumnName + ' LIKE ''' + #ReplaceIDStr + '''' + ' AND PROJID = ''1000''' +
' END'
)
I have also tried using:
'IF COL_LENGTH(''' + #TableName + ''',''PROJID'') IS NOT NULL' +
instead of the column-exist check above. This also still gives me the "Invalid Column Name" messages.
I would be happy to take the column-exist check outside of the 'Exec' statement, but I'm not sure how to go about doing this either.
You just need to do it in a different scope.
IF EXISTS (SELECT 1 FROM sys.columns ...)
BEGIN
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'UPDATE ...';
EXEC sp_executesql #sql;
END
Output the results of this query to text. Don't forget to change the values of the variables! Take the result of this and run it.
SET NOCOUNT ON
DECLARE #ColumnName VARCHAR(200) = 'ReplaceColumn'
, #ReplaceIdStr VARCHAR(200) = 'ExampleReplaceIdStr'
, #FindIdStr VARCHAR(200) = 'ExampleFindIdStr'
PRINT 'BEGIN TRAN'
PRINT 'SET XACT_ABORT ON'
SELECT
'UPDATE ' + C.TABLE_NAME + CHAR(13)
+ 'SET ' + #ColumnName + ' = REPLACE(' + #ColumnName + ', ''' + #ReplaceIdStr + ''', ''' + #FindIdStr + ''')' + CHAR(13)
+ 'WHERE ' + #ColumnName + ' LIKE ''%' + #ReplaceIdStr + '%'' AND PROJID = ''1000''' + CHAR(13)
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.COLUMN_NAME = 'PROJID'
PRINT 'COMMIT TRAN'
SET NOCOUNT OFF
EDIT: Also, some reasoning: You said you want update all tables where they contain a column called PROJID. Your first query just says that if the table #TableName has a PROJID column, then update #ColumnName on it. But it doesn't guarantee that it has #ColumnName on it. The query I gave doesn't check that either, because I'm assuming that all tables that have PROJID also have #ColumnName. If that isn't the case, let me know and I can update the answer to check that. That you're getting an Invalid Column Name error points to #ColumnName not existing.
Your query would have updated one table (#TableName) at most, whereas the one I gave you will update every table that has PROJID. I hope that's what your going for.
EDIT 2: Here is a version that would run it all at once:
DECLARE #ColumnName VARCHAR(200) = 'Value'
, #ReplaceIdStr VARCHAR(200) = 'ExampleReplaceIdStr'
, #FindIdStr VARCHAR(200) = 'ExampleFindIdStr'
DECLARE #Sql NVARCHAR(MAX)
DECLARE UpdateCursor CURSOR FOR
SELECT
'UPDATE ' + C.TABLE_NAME
+ ' SET ' + #ColumnName + ' = REPLACE(' + #ColumnName + ', ''' + #ReplaceIdStr + ''', ''' + #FindIdStr + ''')'
+ ' WHERE ' + #ColumnName + ' LIKE ''%' + #ReplaceIdStr + '%'' AND PROJID = ''1000'''
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.COLUMN_NAME = 'PROJID'
OPEN UpdateCursor
FETCH NEXT FROM UpdateCursor
INTO #Sql
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC sp_executesql #Sql
FETCH NEXT FROM UpdateCursor
INTO #Sql
END
CLOSE UpdateCursor
DEALLOCATE UpdateCursor
I am working with a Stored Procedure in MS SQL 2008.
The problem with my code lies somewhere in the UPDATE section. I am trying to replace a string that begins with a single double-quote.
Here is the string that I'm searching for, and I wish to replace it with nothing. Could this be a problem with escaping quotes, etc?
">%http%<!--
Many thanks.
Below is the stored procedure.
USE [cop_pcms]
GO
/****** Object: StoredProcedure [dbo].[SearchAllTablesWildcard_Replace2] Script Date: 09/11/2012 11:33:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[SearchAllTablesWildcard_Replace2]
(
#SearchStr nvarchar(100)
)
AS
BEGIN
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #SQL NVARCHAR(4000)
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
IF #ColumnName IS NOT NULL
BEGIN
SET #SQL = 'UPDATE ' + #TableName +
' SET ' + #ColumnName + ' = REPLACE(' + #ColumnName + ',' + #SearchStr2 + ',' + ''''')' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
EXEC(#SQL)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
END
I'm having a hard time figuring out what your question is... but...
this should do what you want if you want to just replace a double quote
select REPLACE('testing"testing','"','')
Also this example should work if you want to replace the string ">%http%
select REPLACE('testing">%http%<!--testing','">%http%<!--','')
this however will not do anything
select REPLACE('testing">**http**<!--testing','">%http%<!--','')
To be more clear. this doesn't do it either... note: the % isn't a wildcard in the "pattern"
select REPLACE('1111a23333','1a%3','')
Also QUOTENAME(TABLE_NAME) will put square brackets around that which I think is what you think is happening?
So maybe this is your problem
REPLACE(' + #ColumnName + ',' + #SearchStr2 + ',' + ''''')'
This is replacing the thing... followed by two single quotes.
See: REPLACE (Transact-SQL)
This question already has answers here:
Find a value anywhere in a database
(18 answers)
Closed 10 years ago.
I have a specific value, let's say string 'comments'. I need to find all instances of this in the database as I need to do an update on the format to change it to (*) Comments.
How can I do this? The database is in SQL Server 2000 format.
I've just updated my blog post to correct the error in the script that you were having Jeff, you can see the updated script here: Search all fields in SQL Server Database
As requested, here's the script in case you want it but I'd recommend reviewing the blog post as I do update it from time to time
DECLARE #SearchStr nvarchar(100)
SET #SearchStr = '## YOUR STRING HERE ##'
-- 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
-- Updated and tested by Tim Gaunt
-- http://www.thesitedoctor.co.uk
-- http://blogs.thesitedoctor.co.uk/tim/2010/02/19/Search+Every+Table+And+Field+In+A+SQL+Server+Database+Updated.aspx
-- Tested on: SQL Server 7.0, SQL Server 2000, SQL Server 2005 and SQL Server 2010
-- Date modified: 03rd March 2011 19:00 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', '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
DROP TABLE #Results
I published one here: FullParam SQL Blog
/* Reto Egeter, fullparam.wordpress.com */
DECLARE #SearchStrTableName nvarchar(255), #SearchStrColumnName nvarchar(255), #SearchStrColumnValue nvarchar(255), #SearchStrInXML bit, #FullRowResult bit, #FullRowResultRows int
SET #SearchStrColumnValue = '%searchthis%' /* use LIKE syntax */
SET #FullRowResult = 1
SET #FullRowResultRows = 3
SET #SearchStrTableName = NULL /* NULL for all tables, uses LIKE syntax */
SET #SearchStrColumnName = NULL /* NULL for all columns, uses LIKE syntax */
SET #SearchStrInXML = 0 /* Searching XML data may be slow */
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
CREATE TABLE #Results (TableName nvarchar(128), ColumnName nvarchar(128), ColumnValue nvarchar(max),ColumnType nvarchar(20))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256) = '',#ColumnName nvarchar(128),#ColumnType nvarchar(20), #QuotedSearchStrColumnValue nvarchar(110), #QuotedSearchStrColumnName nvarchar(110)
SET #QuotedSearchStrColumnValue = QUOTENAME(#SearchStrColumnValue,'''')
DECLARE #ColumnNameTable TABLE (COLUMN_NAME nvarchar(128),DATA_TYPE nvarchar(20))
WHILE #TableName IS NOT NULL
BEGIN
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME LIKE COALESCE(#SearchStrTableName,TABLE_NAME)
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0
)
IF #TableName IS NOT NULL
BEGIN
DECLARE #sql VARCHAR(MAX)
SET #sql = 'SELECT QUOTENAME(COLUMN_NAME),DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(''' + #TableName + ''', 2)
AND TABLE_NAME = PARSENAME(''' + #TableName + ''', 1)
AND DATA_TYPE IN (' + CASE WHEN ISNUMERIC(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(#SearchStrColumnValue,'%',''),'_',''),'[',''),']',''),'-','')) = 1 THEN '''tinyint'',''int'',''smallint'',''bigint'',''numeric'',''decimal'',''smallmoney'',''money'',' ELSE '' END + '''char'',''varchar'',''nchar'',''nvarchar'',''timestamp'',''uniqueidentifier''' + CASE #SearchStrInXML WHEN 1 THEN ',''xml''' ELSE '' END + ')
AND COLUMN_NAME LIKE COALESCE(' + CASE WHEN #SearchStrColumnName IS NULL THEN 'NULL' ELSE '''' + #SearchStrColumnName + '''' END + ',COLUMN_NAME)'
INSERT INTO #ColumnNameTable
EXEC (#sql)
WHILE EXISTS (SELECT TOP 1 COLUMN_NAME FROM #ColumnNameTable)
BEGIN
PRINT #ColumnName
SELECT TOP 1 #ColumnName = COLUMN_NAME,#ColumnType = DATA_TYPE FROM #ColumnNameTable
SET #sql = 'SELECT ''' + #TableName + ''',''' + #ColumnName + ''',' + CASE #ColumnType WHEN 'xml' THEN 'LEFT(CAST(' + #ColumnName + ' AS nvarchar(MAX)), 4096),'''
WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ #ColumnName + '),'''
ELSE 'LEFT(' + #ColumnName + ', 4096),''' END + #ColumnType + '''
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + CASE #ColumnType WHEN 'xml' THEN 'CAST(' + #ColumnName + ' AS nvarchar(MAX))'
WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ #ColumnName + ')'
ELSE #ColumnName END + ' LIKE ' + #QuotedSearchStrColumnValue
INSERT INTO #Results
EXEC(#sql)
IF ##ROWCOUNT > 0 IF #FullRowResult = 1
BEGIN
SET #sql = 'SELECT TOP ' + CAST(#FullRowResultRows AS VARCHAR(3)) + ' ''' + #TableName + ''' AS [TableFound],''' + #ColumnName + ''' AS [ColumnFound],''FullRow>'' AS [FullRow>],*' +
' FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + CASE #ColumnType WHEN 'xml' THEN 'CAST(' + #ColumnName + ' AS nvarchar(MAX))'
WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ #ColumnName + ')'
ELSE #ColumnName END + ' LIKE ' + #QuotedSearchStrColumnValue
EXEC(#sql)
END
DELETE FROM #ColumnNameTable WHERE COLUMN_NAME = #ColumnName
END
END
END
SET NOCOUNT OFF
SELECT TableName, ColumnName, ColumnValue, ColumnType, COUNT(*) AS Count FROM #Results
GROUP BY TableName, ColumnName, ColumnValue, ColumnType
You could query the sys.tables database view to get out the names of the tables, and then use this query to build yourself another query to do the update on the back of that. For instance:
select 'select * from '+name from sys.tables
will give you a script that will run a select * against all the tables in the system catalog, you could alter the string in the select clause to do your update, as long as you know the column name is the same on all the tables you wish to update, so your script would look something like:
select 'update '+name+' set comments = ''(*)''+comments where comments like ''%comment to be updated%'' ' from sys.tables
You could also then predicate on the tables query to only include tables that have a name in a certain format, or are in a subset you want to create the update script for.
The below Query works but very slow... copied from vyaskn.tripod.com
Declare #SearchStr nvarchar(100)
SET #SearchStr='Search String' 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