如何修改存储过程以包含多个表

时间:2017-10-26 13:15:09

标签: sql sql-server tsql stored-procedures

嗨,这个存储过程适用于一个表,我想知道它可以扩展到多个表,以便返回的值在技术上搜索多个表。我已经阅读了类似的帖子,这些帖子涵盖了整个数据库,但仅限于一小组表,而不是必须手动完成。

基本上所以最后的执行在下面运行,基本上遍历所有以LZO_AE

开头的表

@table_name ='LZO_AE%'

IF NOT EXISTS (
        SELECT *
        FROM INFORMATION_SCHEMA.ROUTINES
        WHERE ROUTINE_NAME = 'spSearchStringInTable'
            AND ROUTINE_TYPE = 'PROCEDURE'
        )
    EXECUTE ('CREATE PROCEDURE dbo.spSearchStringInTable AS SET NOCOUNT ON;');
GO

ALTER PROCEDURE spSearchStringInTable (
    @SearchString NVARCHAR(MAX)
    ,@Table_Schema SYSNAME = 'dbo'
    ,@Table_Name SYSNAME
    )
AS
BEGIN
    DECLARE @Columns NVARCHAR(MAX)
        ,@Cols NVARCHAR(MAX)
        ,@PkColumn NVARCHAR(MAX)

    -- Get all character columns
    SET @Columns = STUFF((
                SELECT ', ' + QUOTENAME(Column_Name)
                FROM INFORMATION_SCHEMA.COLUMNS
                WHERE DATA_TYPE IN (
                        'text'
                        ,'ntext'
                        ,'varchar'
                        ,'nvarchar'
                        ,'char'
                        ,'nchar'
                        ,'int'
                        )
                    AND TABLE_NAME = @Table_Name
                    AND TABLE_SCHEMA = @Table_Schema
                ORDER BY COLUMN_NAME
                FOR XML PATH('')
                ), 1, 2, '');

    IF @Columns IS NULL -- no character columns
        RETURN - 1;

    -- Get columns for select statement - we need to convert all columns to nvarchar(max)
    SET @Cols = STUFF((
                SELECT ', CAST(' + QUOTENAME(Column_Name) + ' AS nvarchar(max)) COLLATE DATABASE_DEFAULT AS ' + QUOTENAME(Column_Name)
                FROM INFORMATION_SCHEMA.COLUMNS
                WHERE DATA_TYPE IN (
                        'text'
                        ,'ntext'
                        ,'varchar'
                        ,'nvarchar'
                        ,'char'
                        ,'nchar'
                        ,'int'
                        )
                    AND TABLE_NAME = @Table_Name
                    AND TABLE_SCHEMA = @Table_Schema
                ORDER BY COLUMN_NAME
                FOR XML PATH('')
                ), 1, 2, '');
    SET @PkColumn = STUFF((
                SELECT N' + ''|'' + ' + ' CAST(' + QUOTENAME(CU.COLUMN_NAME) + ' AS nvarchar(max)) COLLATE DATABASE_DEFAULT '
                FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
                INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS CU ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
                    AND TC.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
                WHERE TC.TABLE_SCHEMA = @Table_Schema
                    AND TC.TABLE_NAME = @Table_Name
                ORDER BY CU.ORDINAL_POSITION
                FOR XML PATH('')
                ), 1, 9, '');

    IF @PkColumn IS NULL
        SELECT @PkColumn = 'CAST(NULL AS nvarchar(max))';

    -- set select statement using dynamic UNPIVOT
    DECLARE @SQL NVARCHAR(MAX)

    SET @SQL = 'SELECT *, ' + QUOTENAME(@Table_Schema, '''') + ' AS [Table Schema], ' + QUOTENAME(@Table_Name, '''') + ' AS [Table Name]' + ' FROM

  (SELECT ' + @PkColumn + ' AS [PK Column], ' + @Cols + ' FROM ' + QUOTENAME(@Table_Schema) + '.' + QUOTENAME(@Table_Name) + ' ) src UNPIVOT ([Column Value] for [Column Name] IN (' + @Columns + ')) unpvt

 WHERE [Column Value] LIKE ''%'' + @SearchString + ''%'''

    --print @SQL
    EXECUTE sp_ExecuteSQL @SQL
        ,N'@SearchString nvarchar(max)'
        ,@SearchString;
END
GO


execute 
dbo.spSearchStringInTable 
@SearchString = N'410605003', 
@table_schema = 'dbo', 
@table_name ='LZO_AETRIAGETREATMENTHISTORY'

1 个答案:

答案 0 :(得分:0)

您可以使用CURSOR检索匹配的表名,然后在循环中处理每个名称。例如,

ALTER PROCEDURE [dbo].[multi_table_test] AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @table_pattern NVARCHAR(max);
    DECLARE @table_name NVARCHAR(max);
    DECLARE @sql NVARCHAR(max)
    DECLARE @output_table TABLE (table_name NVARCHAR(max), row_count INT);
    DECLARE @row_count INT;

    SET @table_pattern = N'LZO_AE%';
    DECLARE table_list CURSOR FOR
        SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
        WHERE TABLE_NAME LIKE @table_pattern;
    OPEN table_list;
    FETCH NEXT FROM table_list INTO @table_name;
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @sql = N'SELECT @n = (SELECT COUNT(*) FROM [' + @table_name + N'])';
        EXEC sp_executesql @sql, N'@n INT OUTPUT', @n = @row_count OUTPUT;
        INSERT INTO @output_table (table_name, row_count) VALUES (@table_name, @row_count);
        FETCH NEXT FROM table_list INTO @table_name;
    END
    CLOSE table_list;
    DEALLOCATE table_list;
    SELECT table_name, row_count FROM @output_table;
END

返回此

table_name  row_count
----------  ---------
LZO_AE01    3
LZO_AE02    5