【问题标题】:full db substring search case (in)sensitive完整的 db 子字符串搜索大小写(不)敏感
【发布时间】:2016-05-19 19:50:41
【问题描述】:

我想为我的数据库执行完整的数据库子字符串搜索。所以如果一个字段有'hello world,你好吗,我正在寻找如何。结果应显示“hello world [..bla bla bla..]”。此外,我如何添加一个布尔变量,它用于区分大小写或不区分大小写。

我得到了以下代码,但仍然需要上面的东西来集成。有什么推荐吗?

CREATE OR REPLACE FUNCTION search_columns(
    needle text,
    haystack_tables name[] default '{}',
    haystack_schema name[] default '{public}'
)
RETURNS table(schemaname text, tablename text, columnname text, rowctid text)
AS $$
begin
  FOR schemaname,tablename,columnname IN
      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_schema=c.table_schema)
      WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
        AND c.table_schema=ANY(haystack_schema)
        AND t.table_type='BASE TABLE'
  LOOP
    EXECUTE format('SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L',
       schemaname,
       tablename,
       columnname,
       needle
    ) INTO rowctid;
    IF rowctid is not null THEN
      RETURN NEXT;
    END IF;
 END LOOP;
END;
$$ language plpgsql;

干杯

【问题讨论】:

    标签: postgresql search substring case-insensitive postgresql-9.4


    【解决方案1】:

    诚然,我昨晚没有编译这个——如果我编译了,我就会看到错误。你是对的,可选参数必须放在最后。现在我确实有机会编译,这对我有用。

    CREATE OR REPLACE FUNCTION search_columns(
        needle text,
        ignore_case boolean,
        haystack_tables name[] default '{}',
        haystack_schema name[] default '{public}'
    )
    RETURNS table(schemaname text, tablename text, columnname text, column_contents text)
    AS $$
    declare
      like_function text := 'like';
      nneedle text;
    begin
    
      nneedle := '%' || needle || '%';
    
      FOR schemaname,tablename,columnname IN
          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_schema=c.table_schema)
          WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
            AND c.table_schema=ANY(haystack_schema)
            AND t.table_type='BASE TABLE'
      LOOP
        if ignore_case then
          like_function := 'ilike';
        end if;
    
        execute format('SELECT %I FROM %I.%I WHERE cast(%I as text) %s %L',
           columnname, schemaname, tablename, columnname, like_function, nneedle
        ) into column_contents;
    
        IF column_contents is not null THEN
          RETURN NEXT;
        END IF;
    
     END LOOP;
    END;
    $$ language plpgsql;
    

    这里是一个用法示例:

    select *
    from search_columns('hambone', true, array['address_master'], array['sales']);
    

    结果:

    schemaname     tablename      columnname     column_contents
    -----------    ----------     ------------   ---------------------------
    sales          address_master address_desc   Christopher "Hambone" Hamel
    

    【讨论】:

    • 首先非常感谢您的回答,但不幸的是它不起作用。 ERROR : 默认值后面的输入参数也必须有默认值。 SQL 状态:42P13,我认为如果我想要搜索区分大小写或不区分大小写,我无法更改,对吗?对于我刚刚提到的 hello world,如果有一个列标题和一个条目有“hello world, how are you”,而我正在搜索“hello”,它也应该显示上面的条目。
    • 你是绝对正确的......当我起草这个时我没有访问服务器,它有你提到的明显编译错误。既然你告诉我这是一个包容性搜索,我只包括了一个版本,我解决了这个错误。这次我测试过了!
    • 我现在没有完全使用你的代码。不过还是非常感谢!
    【解决方案2】:

    这就是我现在的做法:

    package src;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Scanner;
    import java.util.regex.Pattern;
    
    
    
    /*
    PATTERN MATCHING
    */
    public class BigSearch {
    
        public static void main(String[] args) {
    
                try {
    
                    String keyword;
                    String schema = "public";
                    Boolean caseAware = true;
    
                    System.out.println("Insert the term we shall look for in the database.");
                    Scanner s = new Scanner(System.in);
                    keyword = s.nextLine();
    
                    System.out.println("Do you want the search to be case sensitve "
                            + "\n1 - case sensitive"
                            + "\n0 - case insensitive");
    
                    int caseAwareInt = s.nextInt();
    
                    while (caseAwareInt != 0 && caseAwareInt != 1) {
                        System.out.println("You need to enter 1 or 0. Enter again!");
                        caseAwareInt = s.nextInt();
                    }
    
    
                    if (caseAwareInt == 1) {
                        caseAware = true;
                    } else if (caseAwareInt == 0) {
                        caseAware = false;
                    }
    
                    System.out.println("Your search is now case ");
                    if (caseAware) {
                        System.out.println("sensitive!");
                    }
                    if (!caseAware) {
                        System.out.println("insensitive!");
                    }
    
                    String like = "";
    
                    if (caseAware) {
                        like = "LIKE";
                    } else {
                        like = "ILIKE";
                    }
    
                    Connection conn;
                    Connectivity connectivity = new Connectivity();
                    conn = connectivity.getConnection();
                    Statement stmt = conn.createStatement();
                    Statement stmt2 = conn.createStatement();
                    Statement stmt3 = conn.createStatement();
                    Statement stmt4 = conn.createStatement();
                    Statement stmt5 = conn.createStatement();
    
                    ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM pg_catalog.pg_tables WHERE schemaname = '" + schema + "';");
                    ResultSet tablenames = stmt2.executeQuery("SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = '" + schema + "';");
                    rs.next();
                    int counttables = rs.getInt(1);
                    System.out.println("Tabellen im Schema: " + counttables);
    
                    int appearance = 0;
                    int diftables = 0;
    
                    for (int i = 0; i < counttables; i++) {
                        tablenames.next();
                        ResultSet columnnames = stmt3.executeQuery("SELECT column_name " +
                                "FROM information_schema.columns " +
                                "WHERE table_schema = '" + schema +
                                "'  AND table_name = '" + tablenames.getString(1) + 
                                "'  AND data_type = 'character varying'");
    
                        ResultSet rss = stmt4.executeQuery("SELECT COUNT(*) " +
                                "FROM information_schema.columns " +
                                "WHERE table_schema = '" + schema +
                                "'  AND table_name   = '" + tablenames.getString(1) +
                                "'  AND data_type = 'character varying'");
    
                        rss.next();
                        int countcolumns = rss.getInt (1);
                        System.out.println("Spalten in der Tabelle " + tablenames.getString(1) + ": " + countcolumns);
    
                        int count = 0;
    
                        for (int i2 = 0; i2 < countcolumns; i2++) {
                            columnnames.next();
                            columnnames.getString(1);
    
                            System.out.println("Spaltenname: " + columnnames.getString(1));
                            System.out.println("Tabelle: " + tablenames.getString(1));
    
                            ResultSet containsString;
    
    
                            containsString = stmt5.executeQuery("SELECT * "
                                    + "FROM " + tablenames.getString(1)
                                    + " WHERE " + columnnames.getString(1) + " " + like + " '%" + keyword + "%'");
    
                            while (containsString.next()) {
                                System.out.println(containsString.getString(1) + " -- contains your keyword");
                                appearance++;
                                count ++;
                            }
                        }
                        if (count > 0) {
                            diftables ++;
                        }
                    }
    
                    System.out.println("The keyword was found " + appearance + " times in " + diftables + " different tales.");
    
                } catch (SQLException e) {
                    e.printStackTrace();
                } 
    
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2017-02-21
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 2010-11-26
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      相关资源
      最近更新 更多