How can I control the SQL table aliases that Hibernate uses in its generated queries? - sql

tl;dr: Hibernate automatically generates SQL table aliases in its queries like jurisdicti4_ or this_. Here's an example query:
SELECT
this_.id AS id2_6_3_,
this_.a_table_column AS a_table_column3_6_3_,
jurisdicti4_.b_table_column AS b_table_column4_6_3_,
FROM
app_table_a this_
LEFT OUTER JOIN jurisdiction jurisdicti4_ ON this_.jurisdiction = jurisdicti4_.name
WHERE
this_.a_table_column = ?
I'm using the Hibernate Criteria API to add some hints that need reference the SQL aliases in the query, so I need to know how to either:
specify the SQL table aliases Hibernate will use in its queries (e.g. tell it to use juris instead of jurisdicti4_ for jurisdiction, or
get hibernate to tell me the exact SQL table alias it will use for a particular table or entity (e.g. be told the alias in the query for jurisdiction will be jurisdicti4_.
Full story:
I've inherited a Java app with an Oracle DB that uses Hibernate 4.3.8 and the Hibernate Criteria API to generate some complicated search queries. It recently ran into a severe SQL performance problem that will require us to start to include hints these queries. However, we use Oracle, and its index hints are in the form of:
/*+ index (TABLE_ALIAS INDEX_NAME) */
I've successfully added the needed hints using Criteria.addHint(...), however I've had to hardcode the Hibernate-generated TABLE_ALIAS in the hint string. I'm concerned that over time, the aliases may change, so I want to either control how they're generated or be able to retrieve their values to use when adding the SQL hint.
Edit: This website describes the Hibernate SQL alias generation process: https://prismoskills.appspot.com/lessons/Hibernate/Chapter_23_-_Hibernate_alias_names.jsp
I've found that I have partial control of the SQL aliases when I programmatically set up the join like this: criteria.createAlias(associationPath, alias). The alias value I pass seems to be used as the first part of the SQL alias for the table. However, Hibernate appends some kind of generated table ID integer to that, so I'd get something like myalias4_ in the generated SQL. Also, this only seems to work in joins I setup myself in the criteria. Hibernate will often add its own based on the mappings, and I'm not sure how get this same level of partial control over those.

Related

Documentum -- Custom queries

I am new to learning Documentum and we came across this query being run by the system that we are looking at how to potentially speed up:
SELECT ALL dm_document.r_object_id
FROM dm_document_sp dm_document
WHERE (
dm_document.object_name = :"SYS_B_0"
AND dm_document.r_object_id IN (
SELECT r_object_id
FROM dm_sysobject_r
WHERE i_folder_id = :"SYS_B_1"
)
)
AND (
dm_document.i_has_folder = :"SYS_B_2"
AND dm_document.i_is_deleted = :"SYS_B_3"
)
We looked at adding an index or using a SQL profile. However, the index would be somewhat large and will continue to grow. The SQL profile also would need to be re-examined periodically.
We thought it would be better to look at re-writing the SQL itself. Is there a way to override the system to use custom SQL (i.e. SQL written by the developers) for specific queries that Documentum auto-generates?
Unfortunately there is no way how to alter the default Documentum behavior of translation of DQL into result SQL.
But you can directly execute SQL in your custom applications, jobs, BOFs, components, etc using JDBC. For other than SELECT queries can be also used DQL EXECUTE statement like this:
EXECUTE exec_sql WITH query = 'sql_query'
Another option is to register specific *_s or *_r tables and access them directly in DQL. For example you can register dm_sysobject_s like this:
REGISTER TABLE dm_dbo.dm_sysobject_s ("r_object_id" CHAR(16))
And then you can use it in DQL:
SELECT object_name FROM dm_sysobject_s
And you can also normally join the registered table with Documentum types in DQL, for example:
SELECT object_name FROM dm_sysobject_s s, dmi_queue_item q WHERE s.r_object_id = q.item_id
But keep in mind that this is not recommended approach by Documentum to directly access their internal tables but when you really need to speed up your application then you have to use alternative ways.
Anyway I would recommend to use indexes at first and if it is not suficent then you can continue with steps described above.

Is SELECT INTO T-SQL?

I'm working in a project where I have been explicitly required to not use T-SQL syntax. The application we are using supports T-SQL but we are not allowed to use it to avoid potential migration issues.
My question is: is the SELECT ... INTO statement T-SQL or SQL? If it is T-SQL, is there a specific SQL query to copy an existing table into a new one? (I have tried with CREATE TABLE AS .. FROM but it doesn't work).
Sounds like a very basic question but I haven't been able to find the answer anywhere. Thus, in addition to the question above, it would be very helpful to know if there is a guide/dictionary/website that collects only the standard SQL syntax.
Thanks!
I think they recommend you to use ANSI SQL, instead of T-SQL (SQL Server) or PL-SQL (ORACLE). Considering it as common requirement, every database vendor provide their own way of implementing this requirement. When you use ANSI SQL, you will not have migration issues, when you move from one database vendor to another database vendor.
SQL SERVER
SELECT * INTO new_table
FROM existing_table
ORACLE & ANSI-SQL
CREATE TABLE new_table
AS SELECT * FROM existing_table
is SELECT INTO TSQL or SQL?
Neither. The MySQL documentation claims that SELECT INTO is a Sybase extension to standard sql. As such I don't think you can accurately say it's either of these, but you can say that it's neither. It is indeed used in T-SQL, as well as some other database vendor products, to create a table from a query. The SQL standard says that queries with that goal should be formed as CREATE TABLE blah AS SELECT .... Oracle/MySQL, for example, use the standard form though you can see them use SELECT INTO in a different context, to assign data to variables in stored procedures
If you want to avoid use of this non standard syntax when creating and populating a table then you'll have to:
CREATE TABLE blah (column spec to match query output)
INSERT blah (select query here)
But then you run into nuances like "sqlserver calls it datetime/datetime2 but oracle calls it date/timestamp"
And ultimately you'll probably get into a situation where you just can't use one form of sql to do all you want..
I'd imagine most libraries that do data access on multiple underlying databases have mechanisms to use vendor specific terminology where required
From the answers, it appears you might need to specify which SELECT INTO you're talking about. The other answers seem to suggest there exists some kind of SELECT ... INTO <table-name> when there is also a kind of SELECT ... INTO <local-variable-name list>. The latter is used in embedded SQL for making SQL interact with variables of the host language program. I'm not certain but that variant may also be used in the part of the SQL language that deals with procedures written in SQL (the SQL/PSM part of the standard).
A "reference" that covers "only the standard SQL syntax" is, in principle, the ISO standard document itself, only available by purchase from ISO (and yes, it's ISO not ANSI - ANSI does nothing more than rubberstamping the ISO document after removing all the names of non-US contributors). And not the easiest kind of literature. There are "draft" versions floating around on the internet that might deviate from the published final standards. E.g. http://www.wiscorp.com/sql200n.zip. Note that this is a SQL:2008 draft. Current standard version is SQL:2011. And it's several thousands of pages, so I guess that covers your question "Is all the syntax covered in w3schools standard SQL". (Hint : no)

SQL join using USING: <column name> is not a recognized table hints option

I have the following JOIN:
SELECT * FROM tableA INNER JOIN tableB USING (commonColumn)
I get an error:
"commonColumn" is not a recognized table hints option. If it is
intended as a parameter to a table-valued function or to the
CHANGETABLE function, ensure that your database compatibility mode is
set to 90.
The following instead works:
SELECT * FROM tableA INNER JOIN tableB ON tableA.commonColumn = tableB.commonColumn
The compatibility level in my case is set to 100 (SQL Server 2008), while, by the way, I am working with SQL Server 2012.
What am I doing wrong? I find it very difficult to find example of the use of the keyword USING, as it is almost impossible to do a relevant web search. Yet, it seems the right thing to use when the "joining columns" have the same name...
USING is not supported SQL Server syntax. It's not a reserved keyword, either, so the query engine is using that as a table alias.
It is an ODBC keyword, but those are handled somewhat differently. The engine won't always complain if you use them, but you're not supposed to use them anyways.
It is also listed as a possible future reserved keyword. It's common for new editions of SQL Server to add words to the core reserved list.
Personally, I don't see them adding NATURAL JOIN syntax support, even with USING. A lot of DBAs consider NATURAL JOINs problematic.
The USING keyword is used to specify the source data for MERGE statements (called <table source>) in the documentation.

Documentum Query Language Syntax

I would like to know if there is a way in DQL to fetch the rows based on the start and end row values. (Like row number 1 - 1000, 1001 - 2000). ( Similar to what rownumber in oracle queries).
This input will be of great help.
For Documentum DQL query Pagination you can (should) use RETURN RANGE hint, like this
select * from dm_document where object_name like 'ABC%' enable(RETURN_RANGE 1001 2000 1000 'object_name ASC' )
it will sort documents by object_name and then return up to 1K rows, starting from the row number 1001 ending to 2000, optimized for 1K top (sorted) rows.
Syntax is RETURN_RANGE starting_row ending_row [optimize_top_row] 'sorting_clause'
It works since Content Server CS 6.6 with any underlying database.
Documentum Community Ref
I do not believe this is possible using DQL. However, you can consult the DQL Reference Guide (check Powerlink), which contains information about DQL hints (there is a section on them). There is a discussion of passthrough hints that allow you to pass hints through to the underlying RDBMS. The hints available depend on whether it is Oracle, SQL Server, DB2, etc.
This is an excerpt from that section:
Passthrough hints are hints that are passed to the RDBMS server. They
are not handled by Content Server.
SQL Server and Sybase have two
kinds of hints: those that apply to individual tables and those that
apply globally, to the entire statement. To accommodate this, you can
include passthrough hints in either a SELECT statement’s source list
or at the end of the statement. The hints you include in the source
list must be table‑specific hints. The hints you include at the end of
the statement must be global hints. For example, the following
statement includes passthrough hints for Sybase at the table level and
the statement level:
SELECT "r_object_id" FROM "dm_document" WITH
(SYBASE('NOHOLDLOCK')) WHERE "object_name"='test' ENABLE (FORCE_PLAN)
For DB2 and Oracle, include passthrough hints only at the end of the
SELECT statement.

How do you port a SqlServer database to MySQL?

I have a SqlServer db that I would like to port to MySQL. What's the best way to to this. Things that need to be ported are:
Tables (and data)
FileStream → MySQL equivalent?
Stored Procedures
Functions
Data types are relatively similar.
There is no equivalent to FileStream in MySQL - the files must either be stored as BLOBs, or on the file system while the path is stored in the database.
Migrating away from TSQL means:
There's no WITH clause in MySQL - it will have to converted into a derived table/inline view
There's no TOP syntax - these have to be converted to use LIMIT
There's no ranking/analytic functionality in MySQL - can't use ROW_NUMBER, RANK, DENSE_RANK or NTILE. See this article for alternatives.
MySQL views have notoriously limited functionality:
The SELECT statement cannot contain a subquery in the FROM clause.
The SELECT statement cannot refer to system or user variables.
Within a stored program, the definition cannot refer to program parameters or local variables.
The SELECT statement cannot refer to prepared statement parameters.
Any table or view referred to in the definition must exist. However, after a view has been created, it is possible to drop a table or view that the definition refers to. In this case, use of the view results in an error. To check a view definition for problems of this kind, use the CHECK TABLE statement.
The definition cannot refer to a TEMPORARY table, and you cannot create a TEMPORARY view.
Any tables named in the view definition must exist at definition time.
You cannot associate a trigger with a view.
As of MySQL 5.0.52, aliases for column names in the SELECT statement are checked against the maximum column length of 64 characters (not the maximum alias length of 256 characters).
Dynamic SQL will have to be converted to use MySQL's Prepared Statement syntax
A guide/article with some useful tips is available on the official MySQL dev site.
This is not for the faint of heart. Here is an article that explains what you are in for:
http://searchenterpriselinux.techtarget.com/news/column/0,294698,sid39_gci1187176,00.html