LOBase HSQL avoid having to put table and field names in quote marks - hsqldb

using LO Base with a local HSQL database file.
What I want to do: copy and paste my existing (and in some cases very long) queries, which are of the form:
SELECT table1.field1, table2.field2 FROM table1, table2 WHERE table1.id=table2.id
what I am having to do:
SELECT "table1"."field1", "table2"."field2" FROM "table1", "table2" WHERE "table1"."id"="table2"."id"
I note then when I use LO Base to connect to a remote MySQL database and run the queries, it works fine without the quote marks, but fails when data source is local HSQL database. Is there any way around this? I do not want to have to edit a whole load of complicated queries... any help appreciated

Quotes are required unless the table and field names are upper case, as explained at http://hsqldb.org/doc/2.0/guide/guide.html:
Standard SQL is not case sensitive, except when names of objects are enclosed in double-quotes... all uppercase for unquoted identifiers.
If you don't want this, move the data into a local MySQL instance, or any other database that has case sensitivity without quotes.
Alternatively, write regular expressions that add quotes to your queries before running them. This can be done in LibreOffice Calc, putting the original queries in one column and then a macro-based regular expression formula in the next column that adds the quotes.
It looks like this could get complex, so I would write a macro in Python instead of Basic since there is a regex library. Here is some example code.
import re
def quote_identifier(matchobj):
if matchobj.group(0).upper() in ('SELECT','FROM','WHERE'):
return matchobj.group(0)
else:
return '"{}"'.format(matchobj.group(0))
s = "SELECT table1.field1, table2.field2 FROM table1, table2 WHERE table1.id=table2.id"
result = re.sub("(\w+)", quote_identifier, s)
print(result)
This prints the quoted result:
SELECT "table1"."field1", "table2"."field2" FROM "table1", "table2" WHERE "table1"."id"="table2"."id"

Related

How to run a select sql statement within a field in the Pentaho?

I have a table with a 'query' field containing a select sql and another 'parameters' field containing the sql parameters. I have merged these two fields into a new field containing a correct select sql statement. Now I need to execute this new field containing select sql, get the return from select (the output fields) and generate an excel file.
Use Table-Input if you are interested in a query result set. Table-Input supports SQL parameters, so no need to build the statement yourself using e.g. Replace-In-String, and tripping over escapes on your way. Also, there's variable substitution, just in case you can't live with a single template.
Update 21:14 GMT
I'm not very fond of the way you try to prepare the SELECT statement, but here we go, assuming it's a single statement we have:
Create a job with a Start entry and 2 Transformation entries (T1, T2). Let T1 produce the field containing your SELECT statement and use a Set-Variables step to make the statement available to T2 as variable SELECT. In T2 use a Table-Input step referencing ${SELECT} in the SQL statement text area. Don't forget to enable option "Replace variables in script".
From now on it's a matter of taste. I would prefer to create a CSV file using Text-File-Output. Using the right field separator Excel will open the file after double-clicking it. The advantage of Text-File-Output is that you don't have to specify the fields you don't know at design-time anyway. An empty field list will just handle all fields coming in. Comparable to the total projection in a Table-Input which will create the necessary fields from the retrieved columns downstream.
If you must produce an Excel workbook, you'll have to learn about metadata injection. That would be a separate project for a beginner, though. There are samples in your Kettle installation folder. And there is a very active community if you find yourself in trouble.

What does "SELECT INTO" do?

I'm reading sql code which has a line that looks like this:
SELECT INTO _user tag FROM login.user WHERE id = util.uuid_to_int(_user_id)::oid;
What exactly does this do? The usual way to use SELECT INTO requires specifying the columns to select after the SELECT token, e.g.
SELECT * INTO _my_new_table WHERE ...;
The database is postgresql.
This line must appear inside of a PL/pgSQL function. In that context the value from column tag is assigned to variable _user.
According to the documentation:
Tip: Note that this interpretation of SELECT with INTO is quite different from PostgreSQL's regular SELECT INTO command, wherein the INTO target is a newly created table.
and
The INTO clause can appear almost anywhere in the SQL command. Customarily it is written either just before or just after the list of select_expressions in a SELECT command, or at the end of the command for other command types. It is recommended that you follow this convention in case the PL/pgSQL parser becomes stricter in future versions.

table with "." in its name

I was trying to use sqlFetch. The fetch works perfectly when I change the name of my table to have underlines instead of periods. So if I use the command
sqlFetch(conn, "HelloWorld_40")
It works fine. Unfortunately, my friends are all using the real name of the table
sqlFetch(conn, "HelloWorld.40")
But then it crashes and it tells me that
Error in sqlColumns(conn, "HelloWorld.40") :
'HelloWorld.40': table not found on channel
I'm guessing the period "." is illegal name for a table. But I don't want my friends to change it because it's a lot of people who would be affected. Is there a way I can call the table, or do I have to secretly go to their database, change the name while I use it and then change it back to a period (risking that I will forget, someone will read, blah blah).
Thanks.
put the table name in square brackets:
[HelloWorld.40]
It is a problem with sqlFetch which parse table name. Unfortunately it did not handle table quotes, so it's search for table 40 in schema HelloWorld. You need to directly call sqlQuery (with quoted table name, brackets for MS SQL Server):
sqlQuery(dbhandle, "SELECT * FROM [HelloWorld.40]")
Side note: you should specify which database you are using.
The best delimiter is double quotes -- that should work in most underlying databases:
"HelloWorld.40"
In MySQL, you can also use back ticks (`):
`HelloWorld.40`
In SQL Server, Access, and I think Sybase, you can also use square braces:
[HelloWorld.40]

Use of Like * Works in MS-Access but Not VBA

I have a simple query but am running into problems using LIKE in VBA. My SQL string in VBA is:
stsql1 = "Select Top 25 data.* from data where data.Description Like ('*') "
When I run this sql string in my VBA code I get no records returned, but if I copy/paste the same string into a query in SQL View in MS Access, the query returns the values I expect. Is there a trick to using the "Like" syntax in VBA?
I can provide additional code and a small version of the database if that would help.
For SQL, the database engine will accept either single or double quotes as text delimiters. So either of these 2 WHERE clauses will work.
WHERE some_field Like '*'
WHERE some_field Like "*"
VBA however only accepts double quotes as text delimiters, so you would have to use the second form.
Two other points about your SELECT statement:
Select Top 25 data.* from data where data.Description Like ('*')
TOP [number] is arbitrary without an ORDER BY clause
You don't need parentheses surrounding your Like pattern ... you can use Like "*"
If your VBA code is using ADO with that SELECT statement, you must change the wild card character from * to % ...
WHERE data.Description Like '%'
In ADO/VBA, you have to use % instead of * as the wildcard. I ran into this a couple times in the past ....
Realize that there are at least 2 (yes two!) LIKE operators here.
One is the LIKE operator of VBA.
The other is the LIKE operator of the SQL of the database you are attached to.
The usual wildcards in SQL are % (for any # of any characters) and _ (for one of any character).
Know also that MS Access can open databases that aren't Access; it could be Microsoft SQL Server, or Oracle or IBM DB2. (BTW, the database that is normal for Access is called Microsoft JET.) You may be sheltered from that truth when you create a Query object in Access - in that circumstance, you are using JET SQL even when it's a linked table you are querying.
However, under VBA, when using either DAO or ADO, you're talking directly to whatever the database system happens to be, in which case you MUST use the SQL of that specific system.
OK, short answer: Use % like cularis said.
I can't add a comment, but I think it would be worth noting that you have to use % even if you are querying MS Access.
(example: Outlook VBA runs query on an Access database. The proper query is select * where user like '%bob%', even though this query would not work if plugged directly into an MS Access query).

MS Access SQL DELETE - why would someone specify column names?

I'm having to support an Access .mdb file that someone else has written. One of the button functions in this .mdb calls out to delete some data in an external MSSQL database. All very straightforward, but this syntax isn't something I've seen before:
DELETE
tblEquipmentConnections.SourceEquip,
tblEquipmentConnections.EquipmentConnectionID
FROM tblEquipmentConnections
WHERE
tblEquipmentConnections.SourceEquip = [Forms]![frmEquipment]![EquipmentID];
Is that any different than this?
DELETE
FROM tblEquipmentConnections
WHERE
tblEquipmentConnections.SourceEquip = [Forms]![frmEquipment]![EquipmentID];
I can't find a case where specifying specific columns does anything - but I don't spend much time in Access, so I'm not sure how different the SQL syntax is...
Thanks!
Specifying the column names makes no difference. It's just an Access thing.
The reason they might be there is because Access used to generate DELETE statements that way (not sure if it still does).
The second form without columns names is obviously preferable.
I think the query has been built directly into Access query editor.
And generally we begin by building a select query. Then we change the query type from "Select query" to "Delete query". Then we display the query source by selecting "SQL Mode" where we copy / paste a sql statement like this one :
DELETE qc_Boxes.idBox, qc_Boxes.idScreen, qc_Boxes.title
FROM qc_Boxes;
This is absolutely redundant. The place between DELETE and FROM is used only when the deletion is performed based on a multi-table condition, but even in this case it contains table names and not field names. Also it can contain * which is also redundant. In MySQL, for example it's an incorrect syntax.