full db substring search case(in)sensitive

时间:2016-02-09 17:43:05

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

我想为我的数据库执行完整的数据库子字符串搜索。因此,如果该字段具有'你好世界,你和我在寻找怎样的方式。结果应该显示“你好世界[... bla bla bla ..]'。另外,我如何添加一个布尔变量,用于区分大小写的oder不敏感。

我得到了以下代码,但是stil需要更高级的东西来集成。任何重组?

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;

欢呼声

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

这就是我现在的表现:

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();
            } 

    }

}