How to use PLAN with UPDATE OR INSERT INTO - sql

I am using Firebird 2.5 and came across a problem that I can not resolve by myself.
There is a statement using UPDATE OR INSERT INTO. I would like to make it use a specific execution plan. But - no matter where I place the PLAN - I get following error message (line number varies with PLAN's position):
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 2, column 5.
plan.
I did not find anything about the usage of PLAN with UPDATE OR INSERT INTO in the corresponding documentation.
Aspects of my question: Is it even possible to use them together? Does this work or is it planned to work in a later version of Firebird? Is there an obvious reason it does not work, that I did not see? Which alternatives exist to circumvent this?

It is not possible to do this in Firebird 2.5 (and also not possible in 3.0). Looking at the parser definition, the PLAN clause is only supported on:
select query specification
searched delete
searched update
For a merge statement it should be possible to specify a plan for the source (if it is a select query), but not for the merge itself. The plan clause is not defined for update or insert (nor is it for insert, for example).
As far as I am aware there is nothing planned to add this to Firebird 4. You should consider adding an improvement ticket in the tracker, but I don't know if this is even possible at all.

Related

Postgres 7 strange error

I run an update script on my SQL 7.4.27 DB. I add some constraints and change some column values.
The script is to long for posting here.
The query gives me the following error:
ERROR: could not find trigger 96099812
********** Error **********
ERROR: could not find trigger 96099812
SQL state: XX000
Where can I begin to look for the solution? The error message doesn't give me anything that could help.
7.4 (and up to 8.2 IIRC, haven't double checked in the release notes) had some plan invalidation issues in PL/PgSQL. It'd prepare a plan, then run the cached plan even if DDL had run that'd since caused the plan to make no sense.
That'd be my first suspect for this kind of issue, but it's hard to be too sure - I didn't really get started with PostgreSQL until well after 7.4 came out in late 2003. Yes, that's ten years ago.
I'd take a look in pg_trigger to see if the entry is there, but I couldn't tell you much about what its presence of absence means without seeing the code you ran.

CONTAINS doesn't work with Oracle Text

I am having an issue executing this query.
SELECT * FROM gob_attachment
WHERE CONTAINS (gob_a_document, 'java') > 0
It's giving me
ORA-29902: error in executing ODCIIndexStart() routine
ORA-20000: Oracle Text error:
ORA-00942: table or view does not exist
29902. 00000 - "error in executing ODCIIndexStart() routine"
*Cause: The execution of ODCIIndexStart routine caused an error.
*Action: Examine the error messages produced by the indextype code and
take appropriate action.
After some googling I've disovered that problem could be in index, but when I looked at the table and index they seemed ok to me.
Create script for index is looking like this
CREATE INDEX FTSI_GOB_A_DOCUMENT
ON GOB_ATTACHMENT (GOB_A_DOCUMENT)
INDEXTYPE IS CTXSYS.CONTEXT;
Only thing which is strange to me is that when I look to Edit Table in Table properties in SQL Developer I can see that Operational Status of index is FAILED. Does anyone know what does it mean?Maybe DB rights?
Also it's working when I use
dbms_lob.instr(gob_a_document, utl_raw.cast_to_raw('java')) > 0
instead of contains
Thanks for any advice
P.S. It's related to my previous question Oracle DBMS_LOB.INSTR and CONTAINS performance
UPDATE
After recreating the index and some playing around, I've disovered that I can execute the query above, but it won't return me anything.
If I try it with CONTAINS(gob_a_document, '%'), the result is 26 rows and don't know by which key the query selected them(at least I didn't find anything obvious, I'll investigate it more). Problem could be in that we are using Oracle 10g and storing DOCX files which are supported from version 11.
"Operational Status of index is FAILED"
Okay, this means your CREATE INDEX statement failed. Did you get an error message? I guess the answer is yes but you missed it. So what you need to do is:
drop the index
re-run the CREATE INDEX statement
if it throws an error, make a note of the reason and fix it
In case it's not obvious, the other statement runs because it's not attempting to use your CONTEXT index. It's doing the search the hard way.
"The thing was that the index was already created in DB,"
No the real thing was the index failed to create properly, hence its status. You could just have rebuilt the index, but it is usually better to fix the underlying cause of failure first. That's why I advised you to drop and recreate. Obviously the original failure was due to some ambient condition which no longer applies.
"Now the query is executed, but it's not giving me any results(0 rows
returned). (and I am sure that it should return like 100 rows) "
So that sounds like you are storing documents in a binary format. What sort of documents? Are they in a supported format? That will depend upon which version of Oracle you're using. For instance, Oracle Text 10g supports up t Word 2003 (i.e. DOC only) whereas Oracle Text 11g supports Word 2007 (i.e. DOCX as well).

How can I programmatically run arbitrary SQL statements against my Hibernate/HSQL database?

I'm looking for a way to programmatically execute arbitrary SQL commands against my DB.
(Hibernate, JPA, HSQL)
Query.createNativeQuery() doesn't work for things like CREATE TABLE.
Doing LOTS of searching, I thought I could use the Hibernate Session.doWork().
By using the deprecated Configuration.buildSesionFactory() seems to show that doWork won't work.
I get "use lacks privilege or object not found" for all the CREATE TABLE statements.
So, what other technique is there for executing arbitratry SQL statements?
There were some notes on using the underlying JDBC Statement, but I haven't figure out how to get a JDBC Connection object from Hibernate to try that.
Note that the hibernate.hbm2ddl.auto=create setting will NOT work for me, as I have ARRAY[] columns which it chokes on.
I don't think there is any problem executing a create table statement with a Hibernate native query. Just make sure to use Query.executeUpdate(), and not Query.list() or Query.uniqueResult().
If it doesn't work, please tell us what happens when you execute it, and join the full stack trace of the exception and the SQL query you're executing.
"use lacks privilege or object not found" in HSQL may mean anything, for example existence of a table with the same name. Error messages in HSQL are completely misleading. Try listing your tables using DatabaseMetadata - you have probably already created the table.

How to check a number of inserted/modified records in TADOCommand?

I am using SQL Server database and after calling a simple SQL script I would like to know how many records were affected by last (or only) executed statement in a script.
I cannot find the reference how to achieve this in Delphi's TADOCommand and I know SQL Server gives this information to provider. I am aware of workarounds like getting ##ROWCOUNT in another query, yet this gives some overhead and unnecessary complexity.
Thanks.
Do you use the
function Execute(var RecordsAffected: Integer; const Parameters: OleVariant): _Recordset;
version of the Execute method?
From the doc:
RecordsAffected indicates the number
of records, if the command operates on
data, that are affected by the command
after execution.
So that should give you what you need.
Disclaimer: I cannot test this against SQL Server (don't have it).

INSERT vs INSERT INTO

I have been working with T-SQL in MS SQL for some time now and somehow whenever I have to insert data into a table I tend to use syntax:
INSERT INTO myTable <something here>
I understand that keyword INTO is optional here and I do not have to use it but somehow it grew into habit in my case.
My question is:
Are there any implications of using INSERT syntax versus INSERT INTO?
Which one complies fully with the standard?
Are they both valid in other implementations of SQL standard?
INSERT INTO is the standard. Even though INTO is optional in most implementations, it's required in a few, so it's a good idea to include it if you want your code to be portable.
You can find links to several versions of the SQL standard here. I found an HTML version of an older standard here.
They are the same thing, INTO is completely optional in T-SQL (other SQL dialects may differ).
Contrary to the other answers, I think it impairs readability to use INTO.
I think it is a conceptional thing: In my perception, I am not inserting a row into a table named "Customer", but I am inserting a Customer. (This is connected to the fact that I use to name my tables in singular, not plural).
If you follow the first concept, INSERT INTO Customer would most likely "feel right" for you.
If you follow the second concept, it would most likely be INSERT Customer for you.
It may be optional in mySQL, but it is mandatory in some other DBMSs, for example Oracle. So SQL will be more potentially portable with the INTO keyword, for what it's worth.
In SQL Server 2005, you could have something in between INSERT and INTO like this:
INSERT top(5) INTO tTable1 SELECT * FROM tTable2;
Though it works without the INTO, I prefer using INTO for readability.
One lesson I leaned about this issue is that you should always keep it consistent! If you use INSERT INTO, don't use INSERT as well. If you don't do it, some programmers may ask the same question again.
Here is my another related example case: I had a chance to update a very very long stored procedure in MS SQL 2005. The problem is that too many data were inserted to a result table. I had to find out where the data came from. I tried to find out where new records were added. At the beginning section of SP, I saw several INSERT INTOs. Then I tried to find "INSERT INTO" and updated them, but I missed one place where only "INSERT" was used. That one actually inserted 4k+ rows of empty data in some columns! Of course, I should just search for INSERT. However, that happened to me. I blame the previous programmer IDIOT:):)
They both do the same thing. INTO is optional (in SQL Server's T-SQL) but aids readability.
I started wtiting SQL on ORACLE, so when I see code without INTO it just looks 'broken' and confusing.
Yes, it is just my opinion, and I'm not saying you should always use INTO. But it you don't you should be aware that many other people will probably think the same thing, especially if they haven't started scripting with newer implementations.
With SQL I think it's also very important to realise that you ARE adding a ROW to a TABLE, and not working with objects. I think it would be unhelpful to a new developer to think of SQL table rows/entries as objects. Again, just me opinion.
INSERT INTO is SQL standard while INSERT without INTO is not SQL standard.
I experimented them on SQL Server, MySQL, PostgreSQL and SQLite as shown below.
Database
INSERT INTO
INSERT
SQL Server
Possible
Possible
MySQL
Possible
Possible
PostgreSQL
Possible
Impossible
SQLite
Possible
Impossible
In addition, I also experimented DELETE FROM and DELETE without FROM on SQL Server, MySQL, PostgreSQL and SQLite as shown below:
Database
DELETE FROM
DELETE
SQL Server
Possible
Possible
MySQL
Possible
Impossible
PostgreSQL
Possible
Impossible
SQLite
Possible
Impossible
I prefer using it. It maintains the same syntax delineation feel and readability as other parts of the SQL language, like group BY, order BY.
If available use the standard function. Not that you ever need portability for your particular database, but chances are you need portability for your SQL knowledge.
A particular nasty T-SQL example is the use of isnull, use coalesce!