REGEXP_SIMILAR:
Один из вариантов - использовать REGEXP_SIMILAR()
, который будет более точным, чем LIKE
. Я не уверен, что будет быстрее, но это стоит попробовать:
CREATE MULTISET VOLATILE TABLE TABLEA
(databasename varchar(30), tablename varchar(30))
PRIMARY INDEX (databasename, tablename) ON COMMIT PRESERVE ROWS;
INSERT INTO TABLEA VALUES ('dba','tbla');
INSERT INTO TABLEA VALUES ('dba','tblb');
INSERT INTO TABLEA VALUES ('dbb','tbla');
CREATE MULTISET VOLATILE TABLE TABLEB
(id int, sqlqry VARCHAR(5000))
ON COMMIT PRESERVE ROWS;
INSERT INTO TABLEB VALUES (1, 'SELECT * FROM dba.tbla;');
INSERT INTO TABLEB VALUES (2, 'SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1;');
INSERT INTO TABLEB VALUES (3, 'SELECT * FROM dbb.tbla WHERE foo=bar');
SELECT *
FROM TABLEA
INNER JOIN TABLEB
ON REGEXP_SIMILAR(TABLEB.sqlqry, '^.*' || TABLEA.databasename || '\.' || TABLEA.tablename || '.*$', 'i') = 1;
+-----+------+---+-----------------------------------------------------------------------------+
| dbb | tbla | 3 | SELECT * FROM dbb.tbla WHERE foo=bar |
| dba | tbla | 2 | SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1; |
| dba | tbla | 1 | SELECT * FROM dba.tbla; |
| dba | tblb | 2 | SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1; |
+-----+------+---+-----------------------------------------------------------------------------+
STRTOK_SPLIT_TO_TABLE:
Вот где я целился с этим strtok_split_to_tables
комментарий. По сути, вы разбиваете sql в TABLEB
на слова (разделение по пробелам и ;
символам). Это создаст строку для каждого слова.
Из этого списка вы просто сохраняете слова, содержащие в себе точку (например, databasename.tablename
).
Затем вы можете объединиться между TABLEB и TABLEA:
CREATE MULTISET VOLATILE TABLE TABLEA
(databasename varchar(30), tablename varchar(30))
PRIMARY INDEX (databasename, tablename) ON COMMIT PRESERVE ROWS;
INSERT INTO TABLEA VALUES ('dba','tbla');
INSERT INTO TABLEA VALUES ('dba','tblb');
INSERT INTO TABLEA VALUES ('dbb','tbla');
CREATE MULTISET VOLATILE TABLE TABLEB
(id int, sqlqry VARCHAR(5000))
ON COMMIT PRESERVE ROWS;
INSERT INTO TABLEB VALUES (1, 'SELECT * FROM dba.tbla;');
INSERT INTO TABLEB VALUES (2, 'SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1;');
INSERT INTO TABLEB VALUES (3, 'SELECT * FROM dbb.tbla WHERE foo=bar');
WITH sqlwords AS
(
SELECT tablebid, sqlwordnum, sqlword
FROM TABLE (strtok_split_to_table(TABLEB.id, TABLEB.sqlqry, ' ;')
RETURNS (tablebid integer, sqlwordnum integer, sqlword varchar(100)character set unicode) ) as sqlwordsplitter
WHERE sqlwordsplitter.sqlword like '%.%'
)
SELECT TABLEA.*, TABLEB.*
FROM TABLEA
INNER JOIN sqlwords
ON TABLEA.databasename = strtok(sqlwords.sqlword, '.', 1)
AND TABLEA.tablename = strtok(sqlwords.sqlword, '.', 2)
INNER JOIN TABLEB
ON sqlwords.tablebid = TABLEB.id;
+-----+------+---+-----------------------------------------------------------------------------+
| dbb | tbla | 3 | SELECT * FROM dbb.tbla WHERE foo=bar |
| dba | tbla | 2 | SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1; |
| dba | tbla | 1 | SELECT * FROM dba.tbla; |
| dba | tblb | 2 | SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1; |
+-----+------+---+-----------------------------------------------------------------------------+
Это не будет очень быстрым, так как нам придется разбивать слова, но это определенно получится работа сделана