Algorithm to generate column prefix patterns - java

I am wondering in how to develop a dynamic way to generate column prefix patterns. The main idea is to standardize corporation patterns while defining column names. For example:
If I have to create a column that is a date, so the prefix will be DT_*column_name*;
If it is a name column, so it will be NM_*column_name*;
But if you don't have a well defined pattern, you can suggest a name that need to be approved.
Has anyone ever thought about something like this?
Thank you in advance
**EDIT**
Sorry, I think I didn't explained it enough. It's not exactly for handling type prefixes, but specific business/corporation names. For example (again):
Column customer should be prefixed with CSTM_
Column digit should be prefixed with DIGT_
Column franchising should be prefixed with FRCH_

Dont think is a good idea.
Consider your organization use different DBs like oracle and mysql with different data types.
The column name should be use to describe the column. You alredy have a type of the column defined.
Another drawback is if you want your application to be supported by multipe database engines. Are you going to change the schema ?

Related

Create table query using JDBC doesn't working with different database engines

I write a scala program which interoperates with some database engines (for example MySQL, PostgreSQL).
I use JDBC api to handle SQL queries. I use queries to create table, and I want to create a table with the fields given by users, then these fields are names which can contains spaces or words with accent.
For example, create a table dummy with 2 fields, 'column 1' and 'column 2' as varchar fields.
Writing this query for MySQL database while preserving the spaces contained in the fields, we need to use backticks in the query like :
CREATE TABLE dummy (`column 1` varchar(20), `column 2` varchar(20));
In the same way, the right way to write this query for PostgreSQL while preserving the spaces is :
CREATE TABLE dummy ("column 1" varchar(20), "column 2" varchar(20));
Maybe for another database engine, there is a different way to write this query.
Is there any standard way to write this query with the constrainsts above and using JDBC so that it works with any database engines ?
Thank in advance for your answers.
This doesn't directly address your question as asked, but I think that you would be better off not naming your columns this way. I would 'normalize' the column names (by, e.g. replacing spaces with underscores).
The column names should probably not be exposed directly to the users anyway.
If you need 'human readable' names for columns, I would store them in another table. Or, if it is as simple as preserving spaces, just reverse the process, replacing underscores with spaces.
As already mentioned you should not use spaces, special characters or reserved words as column or table names. To play it safe you can generally put quotes around table and column names to avoid case-sensitivy issues accross databases.
CREATE TABLE "foo" ("id" VARCHAR(32), "bar" VARCHAR(64))
According to SQL-99 standard double quotes (") are used to delimit identifiers. Case sensitivy actually relates to the type of database used and it's settings. There are dbs that will upper- or lowercase your table and column names if they are not quoted but sometimes only in CREATE TABLE or ALTER TABLE commands. Which can lead to runtime errors.
For example CREATE TABLE foo might actually create a table named FOO. When doing a SELECT * FROM foo you might get an error because table foo does not exist but table FOO does exist. Having worked accross lots of DBMS I tend to use quotes for table and column names.
The important part is that you have to stick to writing lowercase or uppercase when using quotes because "foo" is not equal to "FOO" but foo might be equal to FOO depending on the used DBMS. Either do lowercase or uppercase but stick to it if you're using quotes.
You should also avoid database specific column types (stick to ANSI SQL whenever possible).
But doing database migrations by hand is very tedious and error-prone. I would suggest to use migration tools (flyway db) or let the migrations get created by libraries like slick.
As you mentioned scala, please have a look at Slick (http://slick.lightbend.com/) which is a great functional database layer for scala. There are others too but that one I use heavily and can recommend it.

How to determine if a column name must be referred in quotes in a SQL statement?

I am writing a web service that essentially allows users to submit queries to pre-existing tables in various SQL databases against advertised columns.
I have a PostgreSQL table defined like that:
CREATE TABLE stpg.test (
test integer,
"Test" integer,
"TEST" integer
);
insert into stpg.test values (1,2,3);
To determined the names of the available columns I run the following Java code:
ResultSet rs = dbmd.getColumns(null, "stpg", "test", null);
while (rs.next()) {
System.out.println(rs.getString("COLUMN_NAME"));
}
I get:
test
Test
TEST
If a user submits a query, referring to the columns as they were returned, like
select test, Test, TEST from stpg.test he will get 1 1 1 instead of expected 1 2 3.
Is this a bug?
I know that doing select test, "Test", "TEST" from stpg.testreturns results correctly. But my users would not know that to fetch the values of "capitalized" columns that were defined in quotes they need to use quotes in the query.
Is there a way I could could determine that a column name is case sensitive so that I could report its name in quotes? I need to do that generically against different databases, so JDBC api approach is preferable. I tried using ResultSetMetaData and invoking getColumnName and getColumnLabel but they return the names without the quotes. Calling isCaseSensitive always returns false.
Is there a way I could could determine that a column name is case sensitive so that I could report its name in quotes?
It looks like you are saying that a column name needs to be quoted if it contains any upper-case letters. In that case:
if (!name.equals(name.toLowercase())) {
// needs quoting.
}
But this is moot:
if you just quote all column names, or
if you treat user-supplied column names as case insensitive.
(On the latter point, having column names where case sensitivity matters is probably a bad design. Case sensitivity is certainly not something that you'd want your website users to have to worry about ...)
I tried using ResultSetMetaData and invoking getColumnName and getColumnLabel but they return the names without the quotes.
As they should! The quotes are not part of the column names! They are part of the (Postgres) SQL syntax for identifiers (in general). The name is the stuff within the quotes.
Calling isCaseSensitive always returns false.
To be honest, it is not entirely clear (from the javadoc) what the result of that method means. But it sounds like you might have found a bug in the JDBC driver you are using. (Or maybe you are just mistaken. The code for that implements that method in the current Postgres does consult the column type information ...)
I would suggest to always quote the column names. There is no real reason why you would remove the quotes. And, more importantly, the code to decide whether to quote or not is certainly going to span over 10-15ish lines with no added value. That's about 15 lines of code which can introduce new bugs, typos, conceptual errors.
Just quoting each column is straight-forward and always correct!
Also, regarding to your question if the result of select test, Test, TEST from stpg.test is a bug: It's not. It's the default behaviour of PostgreSQL. All column names (or, db-object names) are always lowered except if they are enclosed in quotes. This also leads us to isCaseSensitive. It is always false because it is not case-sensitive.
A more important note: If you let your users type in SQL queries, you will likely run into other weird problems. You will never know what kind of shenanigans your users type. Either by design or by accident ;)
If this is one of the first times you allow users to enter SQL queries, consider your plan of action carefully! Users type errors, mistakes (full-cartesian products on 5 tables with millions of rows? And only then apply filters?... fun times...), or might even try to play with your DB. If you decide on really doing this, buckle up! :) It all depends on the technical knowledge of you user-base.
Also, in Postgres I find it useful to keep everything lower-cased and user underscores to separate words. Like user_account instead of UserAccount.

Get only metadata info about a particular column without looping through them all.. is it possible?

is there an alternative to looping through all the columns of DatabaseMetaData.getColumns() if I want to find only some info about a column I know the name of?
My guess is no, but since I'm new to JDBC... maybe some of you have some suggestions?
Please look at the documentation, it is quite extensive. You can query for a specific column using the fourth parameter columnNamePattern of getColumns():
columnNamePattern - a column name pattern; must match the column name as it is stored in the database
This parameter is a LIKE pattern, so "%" queries all columns, "someColumn" queries for someColumn. Note that if this column is case insensitive you may need to use "somecolumn" or "SOMECOLUMN" depending on the way case insensitive names are stored in your database (see also the various stores* methods in DatabaseMetaData).

Localization design pattern in android

In my database I have a table containing localized cities.
Cities
_id |name_en |name_de |name_it
0 |Rome |Rom |Roma
1 |Munich |München |Monaco
...
Now I want show a ListView where each line exists of all names started by the name in the users language. Also the whole list should be sorted by the city in the users language.
Which is the right design-pattern for this kind of problem?
This is quite a broad question, but here's one general approach:
Get the user's current language ( Get the current language in device )
Query your database with this language code
Bind the returned Cursor to your ListView
Please post your relevant code if you want specific help.
Obviously you need to decide what column to use for SQL request (for both stating which column to retrieve and by which column to sort). So your column names should be public constants. And you need to have a method to return a column name (one of the constants) depending on the current device locale. Use one of the constants as a fallback if the locale does not match any known for the application locales.

MySQL column containing different Java datatypes

I have a table in my MySQL containing calculated values. At the moment this is a Decimal field.
But now I'll need this table to also hold calculated dates, booleans etc.
What's the best solution here, just change the MySQL field type to a VARCHAR and handle the rest in my Java code. Or am I gonna get me in a mess with this approach?
Any ideas and pointers are welcome!
Use a single column per datatype and introduce a discriminator column stating which of the datatype columns should be referenced. The discriminator column can simply be an int representing an enumeration of possible datatypes.

Categories