当前位置: 首页 > news >正文

SQL在一个表中所有列查询某个值

       使用场景:知道表名,同时知道这个表中含有某个字符串,但是不知道这个字符串是在表的哪些列,在列比较多的情况下,查询很麻烦,通过以下语句或者封装的存储可以查出字符串在哪些列出现。结果集里 ContainsValue = 1 就是包含字符串的列。

-- 配置参数
DECLARE @TableName NVARCHAR(128) = 'YourTableName';  -- 替换为实际表名
DECLARE @SearchValue SQL_VARIANT = 'YourSearchValue';  -- 替换为要查找的值
DECLARE @SQL NVARCHAR(MAX) = '';
DECLARE @ColumnName NVARCHAR(128);
DECLARE @ColumnType NVARCHAR(128);
DECLARE @SearchValueStr NVARCHAR(MAX);
DECLARE @IsNumeric BIT;
DECLARE @IsDate BIT;

-- 创建临时表存储结果
IF OBJECT_ID('tempdb..#ColumnSearchResults') IS NOT NULL
    DROP TABLE #ColumnSearchResults;
    
CREATE TABLE #ColumnSearchResults (
    ColumnName NVARCHAR(128),
    ContainsValue BIT
);

-- 将SQL_VARIANT转换为字符串
SET @SearchValueStr = CONVERT(NVARCHAR(MAX), @SearchValue);

-- 预检查是否为数值或日期
SET @IsNumeric = ISNUMERIC(@SearchValueStr);
SET @IsDate = ISDATE(@SearchValueStr);

-- 获取表的所有列名(兼容旧版SQL Server)
DECLARE ColumnCursor CURSOR FOR
SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
  AND DATA_TYPE NOT IN ('image', 'text', 'ntext', 'hierarchyid', 'geometry', 'geography', 'xml', 'timestamp');

OPEN ColumnCursor;
FETCH NEXT FROM ColumnCursor INTO @ColumnName, @ColumnType;

WHILE @@FETCH_STATUS = 0
BEGIN
    -- 处理数值类型(优化算术溢出问题)
    IF @ColumnType IN ('int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real', 'money', 'smallmoney')
    BEGIN
        IF @IsNumeric = 1
        BEGIN
            -- 使用字符串比较避免直接转换搜索值
            SET @SQL = '
            INSERT INTO #ColumnSearchResults (ColumnName, ContainsValue)
            SELECT ''' + QUOTENAME(@ColumnName) + ''', 
                   CASE 
                       WHEN EXISTS (
                           SELECT 1 
                           FROM ' + QUOTENAME(@TableName) + ' 
                           WHERE LTRIM(RTRIM(CONVERT(NVARCHAR(MAX), ' + QUOTENAME(@ColumnName) + '))) = @SearchValue)
                       THEN 1 
                       ELSE 0 
                   END';
        END
        ELSE
            SET @SQL = '
            INSERT INTO #ColumnSearchResults (ColumnName, ContainsValue)
            SELECT ''' + QUOTENAME(@ColumnName) + ''', 0';
    END
    -- 处理日期/时间类型的特殊转换
    ELSE IF @ColumnType IN ('date', 'datetime', 'datetime2', 'smalldatetime')
    BEGIN
        IF @IsDate = 1
            SET @SQL = '
            INSERT INTO #ColumnSearchResults (ColumnName, ContainsValue)
            SELECT ''' + QUOTENAME(@ColumnName) + ''', 
                   CASE 
                       WHEN EXISTS (
                           SELECT 1 
                           FROM ' + QUOTENAME(@TableName) + ' 
                           WHERE CONVERT(NVARCHAR(30), ' + QUOTENAME(@ColumnName) + ', 120) = @SearchValue)
                       THEN 1 
                       ELSE 0 
                   END';
        ELSE
            SET @SQL = '
            INSERT INTO #ColumnSearchResults (ColumnName, ContainsValue)
            SELECT ''' + QUOTENAME(@ColumnName) + ''', 0';
    END
    -- 处理时间类型
    ELSE IF @ColumnType = 'time'
    BEGIN
        -- 检查时间格式是否有效
        IF @IsDate = 1 OR ISDATE('2000-01-01 ' + @SearchValueStr) = 1
            SET @SQL = '
            INSERT INTO #ColumnSearchResults (ColumnName, ContainsValue)
            SELECT ''' + QUOTENAME(@ColumnName) + ''', 
                   CASE 
                       WHEN EXISTS (
                           SELECT 1 
                           FROM ' + QUOTENAME(@TableName) + ' 
                           WHERE CONVERT(NVARCHAR(12), ' + QUOTENAME(@ColumnName) + ', 114) = @SearchValue)
                       THEN 1 
                       ELSE 0 
                   END';
        ELSE
            SET @SQL = '
            INSERT INTO #ColumnSearchResults (ColumnName, ContainsValue)
            SELECT ''' + QUOTENAME(@ColumnName) + ''', 0';
    END
    -- 处理位类型
    ELSE IF @ColumnType = 'bit'
        SET @SQL = '
        INSERT INTO #ColumnSearchResults (ColumnName, ContainsValue)
        SELECT ''' + QUOTENAME(@ColumnName) + ''', 
               CASE 
                   WHEN EXISTS (
                       SELECT 1 
                       FROM ' + QUOTENAME(@TableName) + ' 
                       WHERE ' + QUOTENAME(@ColumnName) + ' = CASE 
                           WHEN @SearchValue IN (''1'', ''true'', ''TRUE'') THEN 1 
                           WHEN @SearchValue IN (''0'', ''false'', ''FALSE'') THEN 0 
                           ELSE NULL 
                       END)
                   THEN 1 
                   ELSE 0 
               END';
    -- 处理其他类型(默认作为字符串比较)
    ELSE
        SET @SQL = '
        INSERT INTO #ColumnSearchResults (ColumnName, ContainsValue)
        SELECT ''' + QUOTENAME(@ColumnName) + ''', 
               CASE 
                   WHEN EXISTS (
                       SELECT 1 
                       FROM ' + QUOTENAME(@TableName) + ' 
                       WHERE ' + QUOTENAME(@ColumnName) + ' = @SearchValue)
                   THEN 1 
                   ELSE 0 
               END';
    
    -- 执行查询
    EXEC sp_executesql 
        @SQL, 
        N'@SearchValue NVARCHAR(MAX)', 
        @SearchValue = @SearchValueStr;
    
    FETCH NEXT FROM ColumnCursor INTO @ColumnName, @ColumnType;
END;

CLOSE ColumnCursor;
DEALLOCATE ColumnCursor;

-- 返回结果
SELECT * FROM #ColumnSearchResults


-- 封装为存储过程

CREATE PROCEDURE UP_SearchAllColumns
    @TableName NVARCHAR(128),
    @SearchValue SQL_VARIANT,
    @ResultTable NVARCHAR(128) = NULL  -- 可选参数:指定结果表名
AS
BEGIN
    SET NOCOUNT ON;

    -- 声明变量
    DECLARE @SQL NVARCHAR(MAX) = '';
    DECLARE @ColumnName NVARCHAR(128);
    DECLARE @ColumnType NVARCHAR(128);
    DECLARE @SearchValueStr NVARCHAR(MAX);
    DECLARE @IsNumeric BIT;
    DECLARE @IsDate BIT;
    DECLARE @ResultTableName NVARCHAR(128);

    -- 设置结果表名
    IF @ResultTable IS NULL
        SET @ResultTableName = '##SearchResults_' + REPLACE(CAST(NEWID() AS NVARCHAR(36)), '-', '_');
    ELSE
        SET @ResultTableName = @ResultTable;

    -- 创建结果表
    SET @SQL = '
    IF OBJECT_ID(''tempdb..' + QUOTENAME(@ResultTableName) + ''') IS NOT NULL
        DROP TABLE ' + QUOTENAME(@ResultTableName) + ';
        
    CREATE TABLE ' + QUOTENAME(@ResultTableName) + ' (
        ColumnName NVARCHAR(128),
        ContainsValue BIT
    );';
    
    EXEC sp_executesql @SQL;

    -- 将SQL_VARIANT转换为字符串
    SET @SearchValueStr = CONVERT(NVARCHAR(MAX), @SearchValue);

    -- 预检查是否为数值或日期
    SET @IsNumeric = ISNUMERIC(@SearchValueStr);
    SET @IsDate = ISDATE(@SearchValueStr);

    -- 检查目标表是否存在
    IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TableName)
    BEGIN
        RAISERROR('目标表不存在: %s', 16, 1, @TableName);
        RETURN;
    END;

    -- 获取表的所有列名(兼容旧版SQL Server)
    DECLARE ColumnCursor CURSOR FOR
    SELECT COLUMN_NAME, DATA_TYPE
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = @TableName
      AND DATA_TYPE NOT IN ('image', 'text', 'ntext', 'hierarchyid', 'geometry', 'geography', 'xml', 'timestamp');

    OPEN ColumnCursor;
    FETCH NEXT FROM ColumnCursor INTO @ColumnName, @ColumnType;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        -- 处理数值类型(优化算术溢出问题)
        IF @ColumnType IN ('int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real', 'money', 'smallmoney')
        BEGIN
            IF @IsNumeric = 1
            BEGIN
                -- 使用字符串比较避免直接转换搜索值
                SET @SQL = '
                INSERT INTO ' + QUOTENAME(@ResultTableName) + ' (ColumnName, ContainsValue)
                SELECT ''' + REPLACE(@ColumnName, '''', '''''') + ''', 
                       CASE 
                           WHEN EXISTS (
                               SELECT 1 
                               FROM ' + QUOTENAME(@TableName) + ' 
                               WHERE LTRIM(RTRIM(CONVERT(NVARCHAR(MAX), ' + QUOTENAME(@ColumnName) + '))) = @pSearchValue)
                           THEN 1 
                           ELSE 0 
                       END';
            END
            ELSE
                SET @SQL = '
                INSERT INTO ' + QUOTENAME(@ResultTableName) + ' (ColumnName, ContainsValue)
                SELECT ''' + REPLACE(@ColumnName, '''', '''''') + ''', 0';
        END
        -- 处理日期/时间类型的特殊转换
        ELSE IF @ColumnType IN ('date', 'datetime', 'datetime2', 'smalldatetime')
        BEGIN
            IF @IsDate = 1
                SET @SQL = '
                INSERT INTO ' + QUOTENAME(@ResultTableName) + ' (ColumnName, ContainsValue)
                SELECT ''' + REPLACE(@ColumnName, '''', '''''') + ''', 
                       CASE 
                           WHEN EXISTS (
                               SELECT 1 
                               FROM ' + QUOTENAME(@TableName) + ' 
                               WHERE CONVERT(NVARCHAR(30), ' + QUOTENAME(@ColumnName) + ', 120) = @pSearchValue)
                           THEN 1 
                           ELSE 0 
                       END';
            ELSE
                SET @SQL = '
                INSERT INTO ' + QUOTENAME(@ResultTableName) + ' (ColumnName, ContainsValue)
                SELECT ''' + REPLACE(@ColumnName, '''', '''''') + ''', 0';
        END
        -- 处理时间类型
        ELSE IF @ColumnType = 'time'
        BEGIN
            -- 检查时间格式是否有效
            IF @IsDate = 1 OR ISDATE('2000-01-01 ' + @SearchValueStr) = 1
                SET @SQL = '
                INSERT INTO ' + QUOTENAME(@ResultTableName) + ' (ColumnName, ContainsValue)
                SELECT ''' + REPLACE(@ColumnName, '''', '''''') + ''', 
                       CASE 
                           WHEN EXISTS (
                               SELECT 1 
                               FROM ' + QUOTENAME(@TableName) + ' 
                               WHERE CONVERT(NVARCHAR(12), ' + QUOTENAME(@ColumnName) + ', 114) = @pSearchValue)
                           THEN 1 
                           ELSE 0 
                       END';
            ELSE
                SET @SQL = '
                INSERT INTO ' + QUOTENAME(@ResultTableName) + ' (ColumnName, ContainsValue)
                SELECT ''' + REPLACE(@ColumnName, '''', '''''') + ''', 0';
        END
        -- 处理位类型
        ELSE IF @ColumnType = 'bit'
            SET @SQL = '
            INSERT INTO ' + QUOTENAME(@ResultTableName) + ' (ColumnName, ContainsValue)
            SELECT ''' + REPLACE(@ColumnName, '''', '''''') + ''', 
                   CASE 
                       WHEN EXISTS (
                           SELECT 1 
                           FROM ' + QUOTENAME(@TableName) + ' 
                           WHERE ' + QUOTENAME(@ColumnName) + ' = CASE 
                               WHEN @pSearchValue IN (''1'', ''true'', ''TRUE'') THEN 1 
                               WHEN @pSearchValue IN (''0'', ''false'', ''FALSE'') THEN 0 
                               ELSE NULL 
                           END)
                       THEN 1 
                       ELSE 0 
                   END';
        -- 处理其他类型(默认作为字符串比较)
        ELSE
            SET @SQL = '
            INSERT INTO ' + QUOTENAME(@ResultTableName) + ' (ColumnName, ContainsValue)
            SELECT ''' + REPLACE(@ColumnName, '''', '''''') + ''', 
                   CASE 
                       WHEN EXISTS (
                           SELECT 1 
                           FROM ' + QUOTENAME(@TableName) + ' 
                           WHERE ' + QUOTENAME(@ColumnName) + ' = @pSearchValue)
                       THEN 1 
                       ELSE 0 
                   END';
        
        -- 执行查询
        BEGIN TRY
            EXEC sp_executesql 
                @SQL, 
                N'@pSearchValue NVARCHAR(MAX)', 
                @pSearchValue = @SearchValueStr;
        END TRY
        BEGIN CATCH
            -- 记录错误但继续处理其他列
            PRINT '处理列 [' + @ColumnName + '] 时出错: ' + ERROR_MESSAGE();
        END CATCH;
        
        FETCH NEXT FROM ColumnCursor INTO @ColumnName, @ColumnType;
    END;

    CLOSE ColumnCursor;
    DEALLOCATE ColumnCursor;

    -- 返回结果
    SET @SQL = 'SELECT * FROM ' + QUOTENAME(@ResultTableName);
    EXEC sp_executesql @SQL;

    -- 如果使用的是临时表,则清理
    IF @ResultTable IS NULL
    BEGIN
        SET @SQL = 'DROP TABLE ' + QUOTENAME(@ResultTableName);
        EXEC sp_executesql @SQL;
    END;
END;    

/*
-- 简单调用(使用临时表)
EXEC up_SearchAllColumns
    @TableName = 'YourTableName', -- 实际表名
    @SearchValue = 'YourSearchValue';  -- 实际要查询的值

-- 指定结果表
EXEC up_SearchAllColumns
    @TableName = 'YourTableName',
    @SearchValue = 'YourSearchValue',
    @ResultTable = 'dbo.SearchResults';

-- 查看结果
SELECT * FROM dbo.SearchResults;
*/

相关文章:

  • 贵州省贵州省建设厅网站google付费推广
  • 如何将自己做的网站天津百度网站快速优化
  • 做网站英文怎么说天津做优化好的公司
  • 西宁做网站最好的公司金融网站推广圳seo公司
  • 网站建设 开发工具 python韶关新闻最新今日头条
  • 随州网站建设优化推广渠道怎么推广自己的微信号
  • 51c嵌入式~电路~合集8
  • MSTP技术解析:提升网络负载均衡
  • 【空间数据分析】全局莫兰指数(Global Moran’s I)
  • MySQL 内置函数 -- 日期函数,字符串函数,数学函数,其他函数
  • 宝塔服务器调优工具 1.1(Opcache优化)
  • Unity2D 街机风太空射击游戏 学习记录 #13 射击频率道具 最高分
  • 远鼎 Odoo 18社区版与企业版功能区别系列文章之四 项目管理
  • 前端登录状态管理:主流方案对比与安全实践指南
  • Web攻防-CSRF跨站请求伪造Referer同源Token校验复用删除置空联动上传或XSS
  • Spark 之 Reuse
  • Docker容器核心操作指南:`docker run`参数深度解析
  • 使用 spark-submit 运行依赖第三方库的 Python 文件
  • iwebsec靶场sqli注入(2)
  • 09-StarRocks安全配置FAQ
  • 行为验证码 AJ-Captcha 使用文档
  • 计算机网络第九章——数据链路层《介质访问控制》
  • CDN+OSS边缘加速实践:动态压缩+智能路由降低30%视频流量成本(含带宽峰值监控与告警配置)
  • SM4算法的Verilog流水线实现(带测试)
  • 最方便的应用构建——利用云原生快速搭建本地deepseek知识仓库
  • IoTDB的基本概念及常用命令