Có cách nào để tìm kiếm một chuỗi trong tất cả các bảng của cơ sở dữ liệu trong SQL Server Management Studio 2008 không?
Tôi muốn tìm kiếm chuỗi nói john
. Kết quả sẽ hiển thị các bảng và hàng tương ứng của chúng có chứa john
.
Có cách nào để tìm kiếm một chuỗi trong tất cả các bảng của cơ sở dữ liệu trong SQL Server Management Studio 2008 không?
Tôi muốn tìm kiếm chuỗi nói john
. Kết quả sẽ hiển thị các bảng và hàng tương ứng của chúng có chứa john
.
Câu trả lời:
Nếu bạn giống tôi và có một số hạn chế nhất định trong môi trường sản xuất, bạn có thể muốn sử dụng biến bảng thay vì bảng tạm thời và truy vấn đặc biệt thay vì quy trình tạo.
Tất nhiên tùy thuộc vào trường hợp máy chủ sql của bạn, nó phải hỗ trợ các biến bảng.
Tôi cũng đã thêm một tuyên bố USE để thu hẹp phạm vi tìm kiếm
USE DATABASE_NAME
DECLARE @SearchStr nvarchar(100) = 'SEARCH_TEXT'
DECLARE @Results TABLE (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
Một chút muộn nhưng hy vọng hữu ích.
Tại sao không thử một số công cụ của bên thứ ba có thể được tích hợp vào SSMS.
Tôi đã làm việc với ApexSQL Search (miễn phí 100%) với thành công tốt cho cả lược đồ và tìm kiếm dữ liệu và cũng có gói công cụ SSMS có tính năng này (không miễn phí cho SQL 2012 nhưng giá cả khá phải chăng).
Thủ tục lưu trữ ở trên là thực sự tuyệt vời; Theo quan điểm của tôi, đó chỉ là cách thuận tiện hơn. Ngoài ra, nó sẽ yêu cầu một số sửa đổi nhỏ nếu bạn muốn tìm kiếm các cột datetime hoặc cột GUID và như vậy
Để cập nhật câu trả lời của TechDo cho máy chủ SQL 2012. Bạn cần thay đổi: 'FROM ' + @TableName + ' (NOLOCK) '
thành FROM ' + @TableName + 'WITH (NOLOCK) ' +
Thông thái khác, bạn sẽ nhận được lỗi sau: Deprecated feature 'Table hint without WITH' is not supported in this version of SQL Server.
Dưới đây là thủ tục lưu trữ được cập nhật đầy đủ:
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 + 'WITH (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
END
Hơi muộn một chút, nhưng bạn có thể dễ dàng tìm thấy một chuỗi với truy vấn này
DECLARE
@search_string VARCHAR(100),
@table_name SYSNAME,
@table_id INT,
@column_name SYSNAME,
@sql_string VARCHAR(2000)
SET @search_string = 'StringtoSearch'
DECLARE tables_cur CURSOR FOR SELECT ss.name +'.'+ so.name [name], object_id FROM sys.objects so INNER JOIN sys.schemas ss ON so.schema_id = ss.schema_id WHERE type = 'U'
OPEN tables_cur
FETCH NEXT FROM tables_cur INTO @table_name, @table_id
WHILE (@@FETCH_STATUS = 0)
BEGIN
DECLARE columns_cur CURSOR FOR SELECT name FROM sys.columns WHERE object_id = @table_id
AND system_type_id IN (167, 175, 231, 239)
OPEN columns_cur
FETCH NEXT FROM columns_cur INTO @column_name
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @sql_string = 'IF EXISTS (SELECT * FROM ' + @table_name + ' WHERE [' + @column_name + ']
LIKE ''%' + @search_string + '%'') PRINT ''' + @table_name + ', ' + @column_name + ''''
EXECUTE(@sql_string)
FETCH NEXT FROM columns_cur INTO @column_name
END
CLOSE columns_cur
DEALLOCATE columns_cur
FETCH NEXT FROM tables_cur INTO @table_name, @table_id
END
CLOSE tables_cur
DEALLOCATE tables_cur
Tôi đã viết một SP cho cái này trả về kết quả tìm kiếm dưới dạng tên Bảng, tên cột trong đó chuỗi từ khóa tìm kiếm được tìm thấy cũng như tìm kiếm các hàng tương ứng như trong ảnh chụp màn hình bên dưới.
Đây có thể không phải là giải pháp hiệu quả nhất nhưng bạn luôn có thể sửa đổi và sử dụng nó theo nhu cầu của mình.
IF OBJECT_ID('sp_KeywordSearch', 'P') IS NOT NULL
DROP PROC sp_KeywordSearch
GO
CREATE PROCEDURE sp_KeywordSearch @KeyWord NVARCHAR(100)
AS
BEGIN
DECLARE @Result TABLE
(TableName NVARCHAR(300),
ColumnName NVARCHAR(MAX))
DECLARE @Sql NVARCHAR(MAX),
@TableName NVARCHAR(300),
@ColumnName NVARCHAR(300),
@Count INT
DECLARE @tableCursor CURSOR
SET @tableCursor = CURSOR LOCAL SCROLL FOR
SELECT N'SELECT @Count = COUNT(1) FROM [dbo].[' + T.TABLE_NAME + '] WITH (NOLOCK) WHERE CAST([' + C.COLUMN_NAME +
'] AS NVARCHAR(MAX)) LIKE ''%' + @KeyWord + N'%''',
T.TABLE_NAME,
C.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLES AS T WITH (NOLOCK)
INNER JOIN INFORMATION_SCHEMA.COLUMNS AS C WITH (NOLOCK)
ON T.TABLE_SCHEMA = C.TABLE_SCHEMA AND
T.TABLE_NAME = C.TABLE_NAME
WHERE T.TABLE_TYPE = 'BASE TABLE' AND
C.TABLE_SCHEMA = 'dbo' AND
C.DATA_TYPE NOT IN ('image', 'timestamp')
OPEN @tableCursor
FETCH NEXT FROM @tableCursor INTO @Sql, @TableName, @ColumnName
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @Count = 0
EXEC sys.sp_executesql
@Sql,
N'@Count INT OUTPUT',
@Count OUTPUT
IF @Count > 0
BEGIN
INSERT INTO @Result
(TableName, ColumnName)
VALUES (@TableName, @ColumnName)
END
FETCH NEXT FROM @tableCursor INTO @Sql, @TableName, @ColumnName
END
CLOSE @tableCursor
DEALLOCATE @tableCursor
SET @tableCursor = CURSOR LOCAL SCROLL FOR
SELECT SUBSTRING(TB.Sql, 1, LEN(TB.Sql) - 3) AS Sql, TB.TableName, SUBSTRING(TB.Columns, 1, LEN(TB.Columns) - 1) AS Columns
FROM (SELECT R.TableName, (SELECT R2.ColumnName + ', ' FROM @Result AS R2 WHERE R.TableName = R2.TableName FOR XML PATH('')) AS Columns,
'SELECT * FROM ' + R.TableName + ' WITH (NOLOCK) WHERE ' +
(SELECT 'CAST(' + R2.ColumnName + ' AS NVARCHAR(MAX)) LIKE ''%' + @KeyWord + '%'' OR '
FROM @Result AS R2
WHERE R.TableName = R2.TableName
FOR
XML PATH('')) AS Sql
FROM @Result AS R
GROUP BY R.TableName) TB
ORDER BY TB.Sql
OPEN @tableCursor
FETCH NEXT FROM @tableCursor INTO @Sql, @TableName, @ColumnName
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT @Sql
SELECT @TableName AS [Table],
@ColumnName AS Columns
EXEC(@Sql)
FETCH NEXT FROM @tableCursor INTO @Sql, @TableName, @ColumnName
END
CLOSE @tableCursor
DEALLOCATE @tableCursor
END
Không cần vòng lặp lồng nhau (vòng lặp bên ngoài qua các bảng và vòng lặp bên trong thông qua tất cả các cột của bảng). Người ta có thể truy xuất tất cả các kết hợp cột bảng (hoặc được chọn / lọc) tùy ý từ INFORMATION_SCHEMA.COLUMNS
và trong một vòng lặp chỉ đơn giản là đi qua (tìm kiếm) tất cả chúng:
DECLARE @search VARCHAR(100), @table SYSNAME, @column SYSNAME
DECLARE curTabCol CURSOR FOR
SELECT c.TABLE_SCHEMA + '.' + c.TABLE_NAME, c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c
JOIN INFORMATION_SCHEMA.TABLES t
ON t.TABLE_NAME=c.TABLE_NAME AND t.TABLE_TYPE='BASE TABLE' -- avoid views
WHERE c.DATA_TYPE IN ('varchar','nvarchar') -- searching only in these column types
--AND c.COLUMN_NAME IN ('NAME','DESCRIPTION') -- searching only in these column names
SET @search='john'
OPEN curTabCol
FETCH NEXT FROM curTabCol INTO @table, @column
WHILE (@@FETCH_STATUS = 0)
BEGIN
EXECUTE('IF EXISTS
(SELECT * FROM ' + @table + ' WHERE ' + @column + ' = ''' + @search + ''')
PRINT ''' + @table + '.' + @column + '''')
FETCH NEXT FROM curTabCol INTO @table, @column
END
CLOSE curTabCol
DEALLOCATE curTabCol
curTabCol
chọn tất cả các kết hợp quan tâm của bảng.column. Sau đó tìm kiếm tất cả các cột cho chuỗi được đưa ra trong biến @search. Nếu một chuỗi (chính xác) như vậy trong truy vấn SQL này (nếu không sử dụng THÍCH '% ...%'), kết hợp tên bảng và cột được in ra.
Điều này rất hữu ích. Tôi muốn nhập chức năng này vào cơ sở dữ liệu SQL Postgre. Nghĩ rằng tôi sẽ chia sẻ nó với bất cứ ai quan tâm. Sẽ có họ một vài giờ. Lưu ý: hàm này tạo một danh sách các câu lệnh SQL có thể được sao chép và thực thi trên cơ sở dữ liệu Postgre. Có lẽ ai đó thông minh hơn thì tôi có thể nhờ Postgre tạo và thực hiện tất cả các câu lệnh trong một hàm.
CREATE OR REPLACE FUNCTION SearchAllTables(_search text) RETURNS TABLE( txt text ) as $funct$
DECLARE __COUNT int;
__SQL text;
BEGIN
EXECUTE 'SELECT COUNT(0) FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = ''text''
AND table_schema = ''public'' ' INTO __COUNT;
RETURN QUERY
SELECT CASE WHEN ROW_NUMBER() OVER (ORDER BY table_name) < __COUNT THEN
'SELECT ''' || table_name ||'.'|| column_name || ''' AS tbl, "' || column_name || '" AS col FROM "public"."' || "table_name" || '" WHERE "'|| "column_name" || '" ILIKE ''%' || _search || '%'' UNION ALL'
ELSE
'SELECT ''' || table_name ||'.'|| column_name || ''' AS tbl, "' || column_name || '" AS col FROM "public"."' || "table_name" || '" WHERE "'|| "column_name" || '" ILIKE ''%' || _search || '%'''
END AS txt
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'text'
AND table_schema = 'public';
END
$funct$ LANGUAGE plpgsql;
Câu trả lời đã được đề cập trong bài đăng này đã nhiều lần tôi chấp nhận một chút vì tôi cũng cần tìm kiếm trong một bảng duy nhất:
(và cũng làm cho đầu vào cho tên bảng đơn giản hơn một chút)
ALTER PROC dbo.db_compare_SearchAllTables_sp
(
@SearchStr nvarchar(100),
@TableName nvarchar(256) = ''
)
AS
BEGIN
if PARSENAME(@TableName, 2) is null
set @TableName = 'dbo.' + QUOTENAME(@TableName, '"')
declare @results TABLE(ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @ColumnName nvarchar(128) = '', @SearchStr2 nvarchar(110)
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
IF @TableName <> ''
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 + ' WITH (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
ELSE
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 + ' WITH (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM @results
END