My client requests to change from using MySQL to PostgreSQL. The database migration ran well, and my codes are using DevArt dotConnect Universal. Things are looking good except for the actual SQL statement.
In my C# code I used,
"SELECT * FROM users WHERE user_name LIKE '%abc%';"
and it worked with MySQL, but when it is connected to the PostgreSQL, I have to change the SQL statement to use,
"SELECT * FROM public.\"users\" WHERE user_name LIKE '%abc%';"
and the searched text is case-sensitive!
How do I,
(a) make the searched text case insensitive?
(b) avoid needing to add [public.] in front of the table name and to double-quote the table name?
I have seen someone posted something here, Accessing a table without specifying the schema name
but I have 120 tables and it will be time consuming. Is there any faster approach to solve my 2 issues described above?
EDIT:
Oh I realized these two statements yields the same result.
SELECT * FROM Public.user;
and
SELECT * FROM \"user\";
(a) make the searched text case insensitive?
ILIKE keyword in PostgreSQL provides case insensitive search
SELECT * FROM users WHERE user_name ILIKE '%abc%';
or
select * from words where LOWER(word) LIKE '%aba%'
Note: if your table name is Users then use SELECT * FROM "Users"
> SQLFIDDLE DEMO
Related
SQL Server: Index columns used in like?
I've tried using the query method in the link above with Postgres (0.3ms improvement), it seems to only work with MySQL (10x faster).
MYSQL
User Load (0.4ms) SELECT * FROM users WHERE reverse_name LIKE REVERSE('%Anderson PhD')
User Load (5.8ms) SELECT * FROM users WHERE name LIKE ('%Anderson Phd')
POSTGRES
User Load (2.1ms) SELECT * FROM users WHERE reverse_name LIKE REVERSE('%Scot Monahan')
User Load (2.5ms) SELECT * FROM users WHERE name LIKE '%Scot Monahan'
Did some googling but couldn't quite understand as I'm quite new to DBs. Could anyone explain why this is happening?
To support a prefix match in Postgres for character type columns you either need an index with a suitable operator class: text_pattern_ops for text etc. (Unless you work with the "C" locale ...)
Or you use a trigram index to support any pattern - then you don't need the "reverse" trick any more.
See:
PostgreSQL LIKE query performance variations
You'll see massive performance improvement for tables of none-trivial size, as soon as an index can be used for the query. Have a look at the query plan with EXPLAIN.
Correct me if I'm wrong, but my understanding is that, in MSSQL, sub-structures of a database like Views, Schemas and Tables can be referenced using object notation such as:
Database.Schema.Table.Column
Each of these objects I believe has their own properties.
I need to replicate the structure of an MSSQL DB in MySQL and I am unsure what is the best practice.
I am thinking about creating tables in MySQL with the following naming convention:
Database
|---SubStructureX.Table
| |---Column_A
| |---Column_B
|---SubStructureY.Table
| |---Column_C
| |---Column_D
|
|
Therefore a MySQL query could look like this:
SELECT Column_A, Column_B FROM SubStructureX.Table
In short, "SubstructureX.Table" is just a table name that contains a dot. I would be doing this for ease of use during replication of the MSSQL structure. I don't care if the things before and after the dot are not objects in MySQL.
Is this good MySQL practice?
In MySQL? No, I would think that it's not good practice to use periods in table names at all. I would think that it's very bad practice. The dot is the reference operator in SQL. That means if you want to refer to a column using fully qualified notation, you do so like this:
SELECT Table.Column_A ...
Or, with backtick quoting:
SELECT `Table`.`Column_A` ...
Now, imagine if your table is named StructureX.Table. Just like with a space, you've got to quote that to escape it because you don't want MySQL to think the dot is an operator. That means your SQL has to look like this:
SELECT `StructureX.Table`.Column_A ...
Or, with backtick quoting:
SELECT `StructureX.Table`.`Column_A` ...
Doesn't that look like a syntax error to you? Like maybe it's supposed to be like this:
SELECT `StructureX`.`Table`.`Column_A` ...
This would be a nightmare to maintain and as a systems analyst I would hate any application or developer that inflicted this nomenclature on me. It makes me want to claw my eyes out.
Microsoft SQL Server is different because it supports multiple schemas within a single database, while MySQL treats schema as a synonym for database. In MS SQL Server, schemas are collections of objects, and you can use them to organize your tables, or apply security to tables as a group. The default schema is dbo, which is why you see that one listed so often. In MS SQL Server syntax, this:
SELECT [StructureX].[Table].[Column_A] ...
Means within the current database, the schema named StructureX, table named Table, and column name Column_A. MS SQL Server actually supports a four part name, with the fourth part being the database:
SELECT [MyDatabase].[StructureX].[Table].[Column_A] ...
Here, MyDatabase is the database name.
That same style works in MySQL, except you have to remember that schema and database are synonymous. So there, this:
SELECT `StructureX`.`Table`.`Column_A` ...
Would mean database StructureX, table Table, and column Column_A.
I Can say yes:
But instead of using table name, make a table some alias like this,
select a.column1 from yourTable as a
Using table alias is a good practice.
I have a database named DELTASTORE in mysql in my cpanel. There are tables like ADMIN,CATAGORY,PRODUCT,ORDER. I have inserted some values in each table.
If I run sql
SELECT * FROM ADMIN
it works nicely.
But if I run sql
SELECT * FROM ORDER
it doesn't work! Instead of that, if I run sql
SELECT * FROM DELTASTORE.ORDER
then it works correctly.
Why does that occur?
Is it important to write database name before table name and give a dot between them all the time?
To leave out the database prefix, you have to set a default database, with
USE databasename
When writing programs to access the database, the API provides a way to do this. For instance, in PHP PDO you specify the default database in the DSN:
mysql:host=hostname;dbname=defaultDB
In MySQLi it's an argument to mysqli_connect(). In the obsolete mysql extension you use mysql_use_database(). There are similar methods in other programming languages.
Additionally, since ORDER is a MySQL keyword, you either have to put it in backticks:
SELECT * FROM `ORDER`
or prefix it with a database:
SELECT * FROM DELTASTORE.ORDER
It's usually best to avoid using MySQL reserved words as table or column names, to prevent problems like this. See Syntax error due to using a reserved word as a table or column name in MySQL
The reason is, that ORDER is a SQL keyword (for ORDER BY, which you use to sort the result lines). So with the database name (or schematic name) you mean the table ORDER.
It's better to not use keywords for the table.
Just need to put brackets.
Select * from `ORDER`
I managed to connect to MySQL DB via Sql Developer following this guide. MySQL DB shows and I can expolre tables via the navigator. However, I could not run SELECT statement to show any of these tables. In MySQL workbench I used to use :
use [database_name]
Then, run select statement in that database. But in Sql developer, I am not sure what should I add to the statement to make it work. I have tried the following:
select *
from [table_name].[database_name];
It does not work. I found this tutorial, but nothing is mentioned about simple select statement. Any help is deeply appreciated.
AFAIK, except MySQL specific commands; all other standard SQL commands like SELECT,INSERT,UPDATE,DELETE should work just fine using SQL Developer. but per your posted query, it looks total strange.
Your query
select * from [table_name]#[database_name];
remove that # sign.
you should qualify like database_name.table_name.
Unless it's a typo, remove those [] as well from your query
statement.
Your query should look like
select * from database_name.table_name;
You can always write your SQL including database as well, in the form of:
database.tablename
such as:
select * from wordpressdb.usertable where username="someone"
What would be the equivalant in MySQL for:
Saving a command for later reuse.
eg: alias command1='select count(*) from sometable;'
Where then I simply type command 1 to get the count for SomeTable.
Saving just a string, or rather part of a command.
eg: select * from sometable where $complex_where_logic$ order by attr1 desc;
WHere $complex_where_logic$ is something I wish to save and not have to keep writing out
Another approach is to create a view with your $complex_where_logic$ and query the view instead of the tables:
CREATE VIEW my_view AS SELECT * FROM sometable WHERE $complex_where_logic$
SELECT my_column FROM my_view ORDER BY some_column
Whenever you query a view, you always get the up-to-date data. Internally, MySQL runs the SELECT given in the CREATE VIEW statement and queries the results in order to obtain the results of your current SELECT. Therefore, a view does not improve performance compared to a single query. There a two main advantages in using views:
you have simpler SELECT statements since you do not have to type complex WHERE or JOIN Syntax again and again
you can use it to control user privileges, e.g. give a user access to a view but not to the original tables; this is not useful in your example, but - for example - you can think of views containing aggregate data only
This "template" feature could be part of client tools. Basically I use Toad. It has record macros feature. I think it is possible to do.
I take it the answer you are looking for isn't 'stored procedures'...?
I found that the best solution for this is just any rich GUI for SQL queries (TOAD, mysql query browser, etc). They offer the ability to save commands and browse them and well, of course, much more.