मेरा संस्करण ...
मैंने इसे स्पष्ट कारणों के लिए "नीडल इन द हैस्टैक" नाम दिया है।
यह प्रत्येक पंक्ति और प्रत्येक कॉलम में एक विशिष्ट मान खोजता है, स्तंभ नाम आदि के लिए नहीं।
खोज निष्पादित करें (पाठ्यक्रम के पहले दो चर के लिए मान बदलें):
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;
फिर परिणाम देखने के लिए, निष्पादित करते समय, दूसरी विंडो से, निष्पादित करें:
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;
इसके बारे में कुछ उल्लेख:
- यह लूप करते समय अवरुद्ध के बजाय कर्सर का उपयोग करता है
- यह प्रगति को प्रिंट कर सकता है (यदि आवश्यक हो तो)
- यह कुछ प्रयासों के बाद बाहर निकल सकता है (अंत में IF को अनफिल्ट करें)
- यह सभी रिकॉर्ड प्रदर्शित करता है
- आप इसे आवश्यकतानुसार धुन सकते हैं
अस्वीकरण:
- इसे उत्पादन वातावरण में न चलाएं!
- यह धीमा है । यदि DB को अन्य सेवाओं / उपयोगकर्ताओं द्वारा एक्सेस किया जाता है, तो कृपया सभी चयनों में, विशेष रूप से डायनामिक चयन वाले सभी तालिका नाम के बाद "(NOLOCK)" के साथ जोड़ें।
- यह SQL इंजेक्शन विकल्पों के सभी प्रकारों के खिलाफ मान्य / सुरक्षा नहीं करता है।
- यदि आपका DB विशाल है, तो अपने आप को कुछ नींद के लिए तैयार करें, सुनिश्चित करें कि कुछ मिनटों के बाद क्वेरी को नहीं मारा जाएगा।
- यह स्ट्रिंग के कुछ मूल्यों को सम्मिलित करता है, जिसमें ints / bigints / smallints / smallints शामिल हैं। यदि आपको उन की आवश्यकता नहीं है, तो उन्हें स्क्रिप्ट के शीर्ष पर टाइमस्टैम्प के साथ एक ही बहिष्करण सूची में डालें।