在所有表中搜索多个值

时间:2018-03-05 17:05:25

标签: sql sql-server performance stored-procedures

以下漂亮的SP返回表格和列名以及值 然而,我感兴趣的是搜索多个值。 我唯一想知道的是表/列名的不同输出而不是值。

所以基本上我想知道我的值存在的所有表/列名 然后从那里我可以进行动态更新查询以重命名现有列中的这些值() 因此,通过进行连接来搜索这些值可能会更好。 我也已经想过将整个数据库堆叠在一个巨大的表中,然后我可以在其中加入类似的表。但是有点头疼......有什么建议吗?

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

2 个答案:

答案 0 :(得分:1)

这取决于您使用的SQL Server版本以及解析文本的功能。我主要使用SQL Server 2005,所以我非常有限,但您可以解析@SearchStr并将值放入临时表中,然后使用它连接回来。

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

或者你可以解析这些值并直接使用它们。

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

答案 1 :(得分:0)

我想我已经得到它,目的是找到我的值存在的所有表,然后根据创建多个更新语句来为例如为原始值添加前缀,我最终做了什么我建议将整个数据库填充到2列并加入这些列(与通过此查询循环每个值相比,这恰好要快得多):

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