mysql: Java api to call mysql metadata service - mysql

Is there any java api to call mysql metadata service? The things I am particularly interested in is getting schema of the table using api not modifying the schema of the table.

The best source for getting table metadata is MySQL itself. Use the INFORMATION_SCHEMA tables/views in MySQL to get this data. You can execute the queries and read the results set back like a normal query.
For table information:
SELECT * FROM INFORMATION_SCHEMA.TABLES
For columns:
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
You can use this form for indexes on InnoDB:
SELECT t.name AS `Table`,
i.name AS `Index`,
GROUP_CONCAT(f.name ORDER BY f.pos) AS `Columns`
FROM information_schema.innodb_sys_tables t
JOIN information_schema.innodb_sys_indexes i USING (table_id)
JOIN information_schema.innodb_sys_fields f USING (index_id)
WHERE t.schema = 'sakila'
GROUP BY 1,2;

Related

MySQL request for Node tree

I have a node tree in a MySQL Base and I want to get result like this
Node_1
Node_1_1
Node_1_1_1
Node_1_1_2
Node_1_2
Node_1_2_1
Node_2
Now I have a query that gives me only one deep child and all rests at the end of a list. ( Node_1_1_2 would be the last in this example )
Here is my code:
SELECT name,
if ( parentId = -1, "Root",
if ( exists( SELECT id FROM citizensTree AS t2 WHERE t1.id = t2.parentId), "Inner", "Leaf")
)
AS type FROM citizensTree as t1
I love this SQL solution:
SELECT t.id, t.name FROM tree t CONNECT BY prioir id = parentId START WITH parentId = -1
But it doesnt work in MySQL
The CONNECT BY is non-standard SQL syntax. It's supported by Oracle and Informix as far as I know, but definitely not MySQL.
MySQL 8.0 supports recursive queries using standard ANSI/ISO SQL syntax. See https://dev.mysql.com/doc/refman/8.0/en/with.html#common-table-expressions-recursive-examples
Earlier versions of MySQL do not support this syntax. You can simulate recursive queries using a variety of workarounds. See my answer to What is the most efficient/elegant way to parse a flat table into a tree?

SQLite / MySQL compatibility issue

I know SQL in SQLite is not completely implemented the same way as in MySql. My problem with the following queries is, that they are not compatible and I like to avoid a conditional if <DBMS> ... else
SQLite query
UPDATE sorties SET state = '#'
WHERE `key` IN (
SELECT `key` FROM sorties
INNER JOIN reports AS r
ON r.sortieId=sorties.`key`);
Error on MySQL:
SQL Error (1093): Table 'sorties' is specified twice, both as a target for 'UPDATE' and as a separate source for data
MySQL query (adapted from here)
UPDATE sorties AS s SET s.state='#'
WHERE s.`key` IN (
SELECT t.sortieId FROM (
SELECT r.sortieId AS sortieId
FROM reports AS r
INNER JOIN sorties AS sort
ON sort.`key`=r.sortieId)
AS t);
Error on SQLite:
SQLiteManager: Likely SQL syntax error: UPDATE sorties AS s SET s.state='#'
WHERE s.key IN ( SELECT t.sortieId FROM (
SELECT DISTINCT r.sortieId AS sortieId
FROM reports AS r
INNER JOIN sorties AS sort
ON sort.key=r.sortieId) AS t); [ near "AS": syntax error ]
Exception Name: NS_ERROR_FAILURE
Exception Message: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [mozIStorageConnection.createStatement]
I can't figure out how to make this queries work on both systems equally!
All I want to have is, that each state of sorties must be '#' when it's key can be found in reports.sortieId.
Maybe there is a different approach for this?
Thank you
The first command reads the key value from the sorties table in the subquery, and then checks whether those key values exist in the sorties table in the outer statement. That check is superfluous; you can just compare the values to the ones in reports directly:
UPDATE sorties
SET state = '#'
WHERE key IN (SELECT sortieId
FROM reports);
As for the second command, SQLite does not support aliasing a table used in INSERT/UPDATE/DELETE because those commands work only on a single table. You can just remove the AS s and replace s with sorties everywhere.

MySQL: union query fails on MySQL 5.5, works on MySQL 5.1

I'm having trouble with a stubborn MySQL query. It's a quite long and complex query, sorry about that. I really did my best to find it myself but I could use a hand here.
The following query is used to emulate a full outer join of column information in the information_schema, and column information in a table called nexedit_schema. The PHP variable $db contains the target database that contains the latter table.
The query actually successfully runs on my own server (MySQL version 5.1), but fails to run on a friend's server (MySQL version 5.5). It claims that I have a syntax error near "ON (schema_tables.db_table..."
I'm probably overlooking something really stupid. Anyone kind enough to help me out?
SELECT information_schema.tables.table_name, schema_tables.db_table, schema_tables.ne_page
FROM information_schema.tables
LEFT JOIN (
(SELECT DISTINCT db_table, ne_page FROM {$db}.nexedit_schema)
AS schema_tables)
ON (schema_tables.db_table = information_schema.tables.table_name
COLLATE utf8_unicode_ci)
WHERE information_schema.tables.table_schema = '{$db}'
AND information_schema.tables.table_name NOT LIKE 'nexedit_%'
UNION
SELECT information_schema.tables.table_name, schema_tables.db_table, schema_tables.ne_page
FROM information_schema.tables
RIGHT JOIN (
(SELECT DISTINCT db_table, ne_page FROM {$db}.nexedit_schema)
AS schema_tables)
ON (schema_tables.db_table = information_schema.tables.table_name
COLLATE utf8_unicode_ci)
WHERE information_schema.tables.table_schema IS NULL
AND schema_tables.db_table NOT LIKE 'nexedit_%'
GROUP BY information_schema.tables.table_name,schema_tables.db_table;
There's unnecessary ) here: AS schema_tables) Should be before AS

How do you run a MySQL query from a rake task?

I'm working on removing duplicates from a legacy database for a client of mine, and I've found a MySQL query to do just that. I want to create a Rake task to run the query for the production server. How would I do that?
MySQL query:
select * from community_event_users;
create table dups as
select distinct username, count(*)
from community_event_users group by username
having count(*) > 1;
delete community_event_users from community_event_users inner join dups
on community_event_users.username = dups.username;
insert into community_event_users select username from dups;
If you are on Rails and using ActiveRecord you can simply use:
ActiveRecord::Base.execute(my_sql)
ActiveRecord::Base.connection.execute(my_sql)
Where my_sql is your SQL string.
For Rails 5 and above you better use:
ApplicationRecord.connection.execute <<~END_OF_SQL
YOUR QUERY HERE
END_OF_SQL

mySQL Nested Query Syntax

I am trying to use a nested query approach to build a query-on-query for my mySQL database and failing to correctly generate output. I am able to import my table into Microsoft Access and build Query1 and then build Query2 on Query1 to get the correct output I'm looking for so I feel like I'm close, I just can't get the right syntax to get the output I'm looking for using a mySQL query approach.
Query1, here is the SQL statement from Access for Query1.
SELECT DISTINCT MediaBuys.DistrictID, MediaBuys.SpenderID, MediaBuys.PG, MediaBuys.SupportType, MediaBuys.PriSupportType
FROM MediaBuys
WHERE MediaBuys.PG ="P";
Query2, if I have built Query1 in Access as above and I run this SQL statement in Access as a separate query built on the first I can generate the output I'm looking for.
SELECT Query1.DistrictID, Query1.SpenderID, Query1.PG, Query1.SupportType, Query1.PriSupportType, Count(Query1.SupportType) AS CountOfSupportType
FROM Query1 INNER JOIN Query1 AS Query1_1 ON Query1.PG = Query1_1.PG AND Query1.SpenderID = Query1_1.SpenderID AND Query1.DistrictID = Query1_1.DistrictID
GROUP BY Query1.DistrictID, Query1.SpenderID, Query1.PG, Query1.SupportType, Query1.PriSupportType
HAVING Count(Query1.SupportType) > 1;
I'd like to be able to produce the same output from a query in mySQL. Since I have the SQL statements of these two queries I feel like this should be doable, I've attempted to build a nested query in a number of different ways and each attempt fails, it seems I can't put together the correct syntax. The most common error I receive is "Error Code: 1146. Table 'Query1' doesn't exist".
Is this doable in mySQL and if so can anyone help me with the correct syntax?
Just like you created the query Query1 in Access, create a view View1 in MySql:
CREATE VIEW View1 AS
SELECT DISTINCT DistrictID, SpenderID, PG, SupportType, PriSupportType
FROM MediaBuys
WHERE PG ='P';
and your query will be:
SELECT
View1.DistrictID, View1.SpenderID, View1.PG, View1.SupportType, View1.PriSupportType,
Count(View1.SupportType) AS CountOfSupportType
FROM View1 INNER JOIN View1 AS View1_1
ON View1.PG = View1_1.PG AND View1.SpenderID = View1_1.SpenderID
AND View1.DistrictID = View1_1.DistrictID
GROUP BY View1.DistrictID, View1.SpenderID, View1.PG, View1.SupportType, View1.PriSupportType
HAVING Count(View1.SupportType) > 1;