Understanding ODBC SQL Grammar - Need Catalog Examples - sql

I've recently learned that ODBC has its own SQL grammar that eliminates SQL dialects, and thus makes all databases look "uniform". However, there is almost a complete absence of meaningful online documentation or discussion about this. Thus I don't have answers to questions like:
What is an example ODBC SQL statement(s) that catalogs all tables in a DB?
What is an example ODBC SQL statement that catalogs all columns in a table, or catalogs the primary key columns in a table?
To expand on the prior two questions, to achieve the same query results, what is an example of native (e.g. T-SQL) versus ODBC SQL?
How do I determine if the SQL I'm authoring is ODBC compliant? Note: I'm usually using SSMS.
Here is the quote that originally introduced me to the existence of an ODBC-specific SQL grammar:
In addition to a standard call-level interface, ODBC defines a standard SQL grammar. This grammar is based on the Open Group SQL CAE specification. MS ODBC Documentation
Elsewhere I found this quote:
Therefore, there are really two choices of grammar to use: the SQL-92 grammar (and the ODBC escape sequences) and a DBMS-specific grammar. Of the two, only the SQL-92 grammar is interoperable, so all interoperable applications should use it. MS docs 'choosing a SQL dialect'
I'd like to answer my own questions, and so I googled "SQL-92 query table catalog". The best I've found is from this link, which in turn offers an ODBC "Using Catalog Functions" link - which is broken. I creatively found a way to locate the "Using Catalog Functions" link myself, and found that it too is vague and provides no examples.
I'd really like to see actual examples, demonstrating true ODBC-compliant SQL catalog queries, and I've still not found anything.
Update
I just spotted my first-ever example code for fetching a catalog with ODBC. This has become very "Alice in Wonder Land" to discover the catalog functions, apparently, are not part of an alleged ODBC SQL grammar. Rather, apparently(?), they are part of (required) SDK signatures. Here is a C++ snippet from that link which demonstrates the SQLTables function.
// all catalogs query
printf( "A list of names of all catalogs\n" );
retCode = SQLTables( hstmt, (SQLCHAR*)SQL_ALL_CATALOGS, SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS );
for ( retCode = SQLFetch(hstmt) ; MySQLSuccess(retCode) ; retCode = SQLFetch(hstmt) )
printCatalog( catalogResult );
At this point, I don't know if the above example represents the bulk of my answer - or if it is just a nuanced part of the answer.

Related

How is the query different from traditional SQL language?

I came across a SQL query which looks different from the traditional SQL syntax. Can someone please tell me how is it functionally different from the one which we are used to? And also, whats this SQL known as?
SELECT activity_hour AT TIME ZONE <Parameters.Time Zone> "activity_hour",
INITCAP(domain_entity) "domain_entity",
bytes_received,
bytes_sent,
bytes_total
FROM recent_subscriber_activity("hour_from$" => <Parameters.Pick a Date>::DATE AT TIME ZONE <Parameters.Time Zone>,
"hour_to$" => <Parameters.Pick a Date>::DATE AT TIME ZONE <Parameters.Time Zone> + INTERVAL '36 hours,
domain_category_grouping$ => TRUE, connection_id$ => <Parameters.connection_id>,domain_category_filter$ => <Parameters.Category>)```
This is PostgreSQL syntax for some features that are either part of newer revisions of the SQL standard, or else they are proprietary extensions to the SQL standard added by PostgreSQL because they thought they would be useful.
Which SQL features are standard depends on the which year's version of the SQL standard are followed. The SQL standard allows vendors to invent their own extensions to standard SQL.
Some of the parts of the syntax above that you might not recognize are:
Using a function as a query source is described here:
https://www.postgresql.org/docs/current/xfunc-sql.html#XFUNC-SQL-TABLE-FUNCTIONS
Passing function arguments with the => syntax is described here:
https://www.postgresql.org/docs/current/sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-NAMED
Type conversions with the :: operator is described here:
https://www.postgresql.org/docs/current/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS
The AT TIME ZONE operator is described here:
https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT
All brands of SQL database have their own vendor-specific syntax and enhanced features. It's worthwhile to study the documentation of the brand of SQL database you use, to get accustomed to their features.

Compatibility of "column as alias" vs "alias = column"

I've found that over the years my habits have changed and I much prefer writing queries like this:
select FriendlyName = some_column from some_table
as opposed to this:
select some_column as FriendlyName from some_table
Lately I've been reviewing scripts written by some SQL experts which were designed to work across multiple database versions and platforms and I only ever see the latter syntax.
This was never a concern for me before as a software developer knowing specifically what version of SQL Server my code would be run on, but now I'm writing code that I would like to make as accessible to as many versions/platforms as possible. At least, I'd like to write it so the least amount of modifications are necessary to run on additional versions when the time comes.
That said, my question is whether the former syntax (alias = some_column) has always been part of the SQL specification and will run on any database, or would it not work in some platforms or older versions?
The alias = syntax is specific to SQL Server. The standard is either:
<expression> as alias
<expression> alias
That is, the as is optional -- although I strongly encourage using it.
It is a shame that you have adapted to a syntax that is not available in other databases, and can actually mean other things. In most other databases that accept the syntax, it will be interpreted as a boolean comparison -- and often generate an error because alias is not defined.
And, unfortunately, this syntax convention makes it harder to SQL Server to support a real boolean type, which would be a convenience.

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)

BigQuery DATE_DIFF Error: Encountered " <STRING_LITERAL>

I'm trying the following query from the BigQuery Standard SQL documentation:
SELECT DATE_DIFF(DATE '2010-07-07', DATE '2008-12-25', DAY) as days_diff;
https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#date_diff
However, I'm receiving the following error from the UI:
Error: Encountered " "\'2010-07-07\' "" at line 1, column 23. Was expecting: ")" ... [Try using standard SQL (https://cloud.google.com/bigquery/docs/reference/standard-sql/enabling-standard-sql)]
This is a simple copy and paste from the doc into the web UI Query Editor.
Any idea on how to resolve this?
Below are examples for respectively BigQuery Legacy SQL and Standard SQL
Make sure you try code as it is in answer below - not just second lines but 2(both) lines including first line that looks like comment - but in reality important part of query as it controls which SQL dialect will be in effect!
#legacySQL
SELECT DATEDIFF(DATE('2010-07-07'), DATE('2008-12-25')) AS days_diff
and
#standardSQL
SELECT DATE_DIFF(DATE '2010-07-07', DATE '2008-12-25', DAY) AS days_diff
both returns result as below
Row days_diff
1 559
Ideally, you should consider migrating to Standard SQL
Although the answer has already been provided in the comments to your questions and by Mikhail in the other answer, let me share with you a complete answer that hopefully addresses all your doubts:
ERROR MESSAGE
As explained in the error message you are getting, [Try using standard SQL (...)]. You are trying to run this sample using Legacy SQL (which instead would use the DATEDIFF function). You are actually right, you are running the exact same query provided in the documentation, but the issue here is that the documentation you are using is for Standard SQL (the preferred query language in BigQuery), but you are instead using Legacy SQL (the default language in the old UI, the one you are using).
CHANGE THE QUERY LANGUAGE IN USE
First of all, I would like to remark the importance of using Standard SQL instead of Legacy SQL, as the former adds new functionalities and is the current recommended language to use with BigQuery. You can see the whole list of comparisons in the documentation, but if you are starting with BigQuery, I would just go straight away with Standard SQL.
Now, that being clarified, in order to use Standard SQL instead of Legacy SQL, you can have a look at the documentation here, but let me summarize the available options for you:
In the BigQuery UI, you can toggle the Use legacy SQL option inside
the Show options menu. If this option is marked, you will be using
Legacy SQL; and if it is not, you will be using Standard SQL.
You can use a prefix in your query, like #standardSQL or #legacySQL, which would ignore the default configuration and use the language you specify with this option. As an example on how to use it, please have a look at the other answer by Mikhail, who shared with you a couple of examples using prefixes to identify the language in use. You should copy the complete query (including the prefix) in the UI, and you will see that it works successfully.
Finally, as suggested by Elliott, you can use the new UI, which has just recently released in Beta access. You can access it through this link https://console.cloud.google.com/bigquery instead of the old link https://bigquery.cloud.google.com that you were using until now. You can find more information about the new BigQuery Web UI in this other linked page too.

jOOQ MERGE support for PostgreSQL conditional insert

I had understood that jOOQ would simulate SQL MERGE on systems (such as PostgreSQL) that don't support it.
I have a table with a serial (autoincrement) "id" column and a string "uri" column. I want to use numeric IDs instead of URIs in my database, so I have to make sure I have a URI in the ID lookup table. So following the example in the jOOQ manual, I thought this would work:
createDSLContext().mergeInto(tableByName("uris"))
.using(createDSLContext().selectOne())
.on(fieldByName("uri").equal("http://example.com/"))
.whenNotMatchedThenInsert(fieldByName("uri"))
.values("http://example.com/").execute();
This gives me a DataAccessException saying something like:
SQL [merge into "uris" using (select 1) on "uri" = ? when not matched then insert ("uri") values (?)]; ERROR: syntax error at or near "merge"
But then the log says jOOQ goes ahead and tries to execute the query with bind values. But the table is never updated. So I'm guessing the jOOQ doesn't simulate MERGE on PostgreSQL?
So I then try the H2 database syntax:
createDSLContext().mergeInto(tableByName("uris"), fieldByName("uri")).values(uri.toString()).execute();
I get:
The H2-specific MERGE syntax is not supported in dialect : POSTGRES
What!? But the jOOQ documentation says that the H2 syntax "can be fully simulated by jOOQ for all other databases that support the SQL standard." Surely PostgreSQL supports the SQL standard. Does it really mean "...the SQL standard version of MERGE?"
Is there any way to get PostgreSQL support for MERGE via jOOQ, or am I stuck doing the same workarounds I would do anyway?
To be sure if a given SQL feature is supported by jOOQ for your database, please consider the Javadoc's #Support annotation on the relevant DSL method. This is also documented in the manual. In this case, DSLContext.mergeInto(), where you can see that this statement is currently only supported for these SQLDialects:
#Support(value={CUBRID,DB2,HSQLDB,ORACLE,SQLSERVER,SYBASE})
MERGE is a very powerful statement that is not really easy to emulate if your database doesn't natively support it.
"can be fully simulated by jOOQ for all other databases that support the SQL standard." Surely PostgreSQL supports the SQL standard. Does it really mean "...the SQL standard version of MERGE?"
Yes of course, the SQL standard MERGE statement must be supported :-) We'll clarify this in the manual. I have registered issue #3183 for this.
Is there any way to get PostgreSQL support for MERGE via jOOQ, or am I stuck doing the same workarounds I would do anyway?
Right now, unfortunately, we don't have a solution for this in PostgreSQL. Feel free to discuss possible solutions on the jOOQ User Group.
Yes , it can support which database support the merge in SQL stand.
but postgresql unsupport this feature in SQL standard.
Please see
F312 MERGE statement
F313 Enhanced MERGE statement
F314 MERGE statement with DELETE branch
http://www.postgresql.org/docs/9.3/static/unsupported-features-sql-standard.html