代码之家  ›  专栏  ›  技术社区  ›  sergionni

SQL为可能包含特定值的所有记录选择

  •  2
  • sergionni  · 技术社区  · 14 年前

    如何选择可能包含已知特定值的所有记录, 不涉及具体栏目

    例如,我知道 未知的 列包含值“xxx”,并且有

    非常感谢。

    7 回复  |  直到 14 年前
        1
  •  9
  •   APC    6 年前

    所以,你想在你的数据库上做一个类似Google的自由文本搜索。这是可以做到的,但表现会很糟糕!谷歌之所以这么快,是因为它的索引上有索引,有重复的数据存储,而且通常会为这种搜索优化一切。

    SQL> set serveroutput on size unlimited
    SQL> declare
      2      dummy varchar2(1);
      3  begin
      4      for r in ( select table_name, column_name from user_tab_cols
      5                 where data_type in ('VARCHAR2', 'CHAR', 'CLOB') )
      6      loop
      7          begin
      8              execute immediate 'select null from '||r.table_name
      9                      ||' where '||r.column_name||' like ''%&search_value%'' '
     10                      ||' and rownum = 1'
     11                 into dummy;
     12              dbms_output.put_line('Found it in >>>'
     13                     ||r.table_name||'.'||r.column_name);
     14          exception
     15              when others then
     16                  -- bad practice ahoy!
     17                  null;
     18          end;
     19      end loop;
     20  end;
     21  /
    Enter value for search_value: MAISIE
    old   9:                ||' where '||r.column_name||' like ''%&search_value%'' '
    new   9:                ||' where '||r.column_name||' like ''%MAISIE%'' '
    Found it in >>>T23.NAME
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    更健壮的实现可能需要处理大小写、整词等。如果您使用10g或更高版本,则正则表达式可能会很有用,但是将regex和动态SQL结合起来是一个,呃, 有趣的

    我再说一遍,表演会很烂的!在一个大数据集上。这实际上是不可能调整的,因为我们不能索引每一列,当然也不支持相似或相似的模糊匹配。另一种方法是使用XQuery生成数据的XML表示,然后使用文本对其进行索引。维护这样一个存储库将是一项开销,但是如果您需要定期使用此功能,特别是在生产环境中,那么这项工作将是一项合理的投资。


    all_tab_cols

    for r in ( select owner, table_name, column_name from all_tab_cols
                       where data_type in ('VARCHAR2', 'CHAR', 'CLOB') )
    

    execute immediate 'select null from '||r.owner||'.'||r.table_name
                           ||' where '||r.column_name||' like ''%
    
        2
  •  2
  •   Māris Kiseļovs    14 年前
    SELECT * FROM table WHERE column='xxx';
    

    但如果有许多列可以包含此值,则需要使用或:

    SELECT * FROM table WHERE column1='xxx' or column2='xxx' or column3='xxx';
    
        3
  •  2
  •   Marco Mariani    14 年前

    如果不能显式地写入所有可能的列,则应生成 dynamic SQL query metadata .

        4
  •  1
  •   dpbradley    14 年前

    如果你需要这样做一次或两次那么APC的答案是好的。如果这是一个正在进行的需求的一部分(不寒而栗),那么我认为最好的方法是在一个或多个感兴趣的表上创建一个Oracle计算字段并搜索该字段。使用您确定不会显示在实际文本值中的分隔符,例如:

    alter table mytable add search_column 
     as (mycolumn1||'^'||mycolumn2||'^'||mycolumn3);
    

    select <whatever transformation you want to see here> 
    from mytable where search_column like '%^xxx^%'
    

    (你刚才听到的声音可能是科德在坟墓里旋转的声音)

        5
  •  0
  •   Sagar Varpe    14 年前

    选择*from table_name where(table_Attribute='XXX');

        6
  •  -1
  •   Shantanu Gupta    14 年前

    运行此命令以获得所需的结果,sry用于错误的命名。

    declare @_var nvarchar(1000)
    declare @var1 nvarchar(1000)
    declare @var2 nvarchar(1000)
    declare _cur cursor 
    for select 
    
    case Column_name 
                when '' then '' 
                else Column_name+'=''asd'' OR ' 
            end 
    from information_schema.columns 
        where table_name='M_Patient' 
                and 
              data_type ='nvarchar'
    
    open _cur
    fetch _cur into @_var
    while(@@fetch_status=0)
    begin
    set @var2=isnull(@var2,'')+@_var
    fetch _cur into @_var
    
    end
    close _cur
    deallocate _cur
    
    set @var1='select * from M_Patient where '+ substring(@var2, 0,len(@var2)-2)
    
    execute (@var1)
    
        7
  •  -1
  •   ramad    14 年前

    如果需要在数据库中搜索值,但不知道表和/或列,则通常使用此脚本。只需设置@SearcStr参数并按下play。也许它能帮助你。

    DROP TABLE #Results
    
    DECLARE @SearchStr nvarchar(100)
    SET     @SearchStr = ''
    
    CREATE TABLE 
        #Results(ColumnName nvarchar(370), ColumnValue nvarchar(3630))
    
    SET NOCOUNT ON
    DECLARE @TableName nvarchar(256)
    DECLARE @ColumnName nvarchar(128)
    DECLARE @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')
                    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