missing SELECT keyword error from INSERT statement - sql

Alright, I've got this command:
INSERT INTO PHOTOS_HEADER (TC_CLOCK, DC_SCANDATE, TC_PO, DC_DATE, NC_PACKAGES)
VALUES (:TC_CLOCK, TO_DATE(:DC_SCANDATE, :DATE_FORMAT), :TC_PO, TO_DATE(:DC_DATE, :DATE_FORMAT), :NC_PACKAGES)
RETURNING NC_AUTOID into :OUTPUT
I'm running it in .NET through an OracleCommand object, and it runs find on our local 11g server. When this same code runs on a client site, we get this error:
ORA-00928: missing SELECT keyword
Could it be the returning statement? Could it be to_date? I'm working on finding out what version of the Oracle server the client is using, but any suggestions in the mean time?
Edit: Client is running Oracle 11, same as us. Removed the returning into clause, but still receiving the same error.

I was asked in a comment what to do if you need to work with a version of Oracle without returning. I think that's different enough from the spirit of an answer about whether returning exists to place in its own answer.
One approach is to use the nextval function from a sequence and get the ID before the insert.
select sequence.nextval into :id from dual;
Then perform the insert.
See http://www.dba-oracle.com/t_oracle_nextval_function.htm for more examples.

It is very likely their version of oracle does not support the returning clause. to_date in values has worked since I started playing with Oracle around Oracle 7 in 1998.
According to http://www.dba-oracle.com/plsql/t_plsql_dml.htm the returning clause was added in Oracle 9I release 2.

Related

Validate PL/SQL without permanent changes in database

Is it possible to validate a PL/SQL code without permanent changes.
I know one can commit and then rollback, but I'm looking if there's another solution.
If I write a procedure and I want to know it will compile correctly for example.
I'm using Oracle SQL Developer and didn't see any option to do this.
You can compile your procedure and check if it's valid (doesn't return compilation error).
But in this case Oracle does just Syntactic and Semantic analysis.
Syntactic analysis – Oracle verifies that keywords, object names, operators, delimiters, and so on are placed correctly in your SQL statement. So such queries like select * foRm dual will fail during this validation. For example, we can get here such errors like:
ORA-00900: invalid SQL statement
ORA-00923: FROM keyword not found where expected
ORA-00924: missing BY keyword
ORA-00933: SQL command not properly ended
…
Semantic analysis – it verifies that references to host variables and database objects are valid(including their grants) and that host-variable datatypes are correct. For example, select * from nonexisting_table will fail this validation.
Ie, you will not get errors like ORA-00979 not a group by expression on these steps, since Oracle them later, during optimization phase.
More about this:
http://orasql.org/2017/05/01/sql-validation-during-plsql-compilation/
A different answer is to try the editions feature which has been around for awhile now

How to use PLAN with UPDATE OR INSERT INTO

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.

Oracle equivalent of PostgreSQL INSERT...RETURNING *;

I've converted a bunch of DML (INSERT/UPDATE/DELETE) queries from Oracle into PostgreSQL and now I need to check whether they produce the same set of rows, i.e. that delete removes the same rows, assuming the oracle and postgresql databases contain the same data initially, update updates the same rows etc. On PostgreSQL side, I can use the returning clause with DML statements, i.e.
INSERT INTO test(id, name) VALUES(42, 'foo') RETURNING *;
What's good about the statement above is that I can prepend 'returning *' to any DML statement without knowing the structure or even the name of the table it's executed against and just get all rows like it's a select statement.
However, it seems to be not that shiny on the Oracle side. According to the documentation, Oracle 8i (the one I'm working with) supports RETURNING clause, but it has to store the result into variables and there seem to be no obvious way to get all result columns instead of manually specifying the column name.
Hence, the question is if there is an oracle statement (or sequence of statements) to emulate PostgreSQL 'returning *' without hard-coding table or column names. In other words, is there a way to write an Oracle function like this:
fn('INSERT INTO test(id, name) VALUES(42, ''foo'')')
It should return the set of rows inserted (or modified in the generic case) by the SQL statement.
Update:
I actually found a very similar question (for the conversion from SQL server, not PostgreSQL, into Oracle). Still, I'd love to hear a more simple answer to that if possible.
I could imagine a solution involving EXECUTE IMMEDIATE, RETURNING, and REF CURSOR, but clearly it will be far from simple. I've previously found solutions such as this one, involving XML to problems where records of arbitrary type are to be used. They're quite freaky, to say the least. I guess you'll have to resort to running two separate queries... Specifically, with Oracle 8i, I'm afraid you won't even be able to profit from most of those features.
In short, I don't think there is any SQL construct as powerful as Postgres ... RETURNING clause in Oracle.
It's not currently possible, especially in an old version of Oracle such as 8i. See this answer to a similar question.

How does the "With" keyword work in SQL?

So many times seen with and, so many times SQL Server ask that with has ; before it
How does ;with ... work??
;with coords(...) as (
SELECT * ...
)
Why must have ; before it?
The semicolon is used in SQL to end a query. Putting it before a query like that is just to make sure that the database understands that any previous query has ended.
Originally it was required after each query as they were entered line by line, so the database had to know when to run the query. When the entire query is sent in a single string, you only need semicolons in the case where the SQL syntax is not enough to determine where a query ends. As the with keyword has different uses a semicolon is sometimes needed before it to make sure that it's not part of the previous query.
Using WITH for CTEs requires the previous statement to be terminated with ;. Using it at the start like this guarantees correct syntax
So does MERGE in SQL Server 2008
See this SO question: Incorrect syntax near the keyword 'with'...previous statement must be terminated with a semicolon
It is best practise to terminate every SQL statement with a semicolon. The SQL Server docs (for example here) suggest doing so will be mandated in a future version to there's really no excuse for not getting into the habit now.
To answer the question: you see ;WITH... on Stackoverflow because EITHER the person answering is a sloppy coder OR the person answering assumes the person asking the question is a sloppy coder (and they'll claim it is the latter when it is the former :) The definition of "sloppy coder" here is someone who only uses a semicolon when they are forced to do so.
The use of WITH is for common table expressions (CTEs). They were trying to force the CTE to be defined as the first statement (i.e. cannot be linked with other parts of the query hence the ;)

MySQL Subquery is failing on MySQL 4.0 with invalid syntax error

I'm running a pretty basic subquery on MySQL 4.0.30.
My goal is to get the user permissions from the mysql.user table for any user with grants on a specific database, as noted in the mysql.db table. The query looks like this:
mysql> select * from mysql.user where User IN
(select User from mysql.db where Db='db_name')\G
As you can see, it's pretty basic and follows the subquery syntax in the MySQL manual. However, when I execute that, it errors with the following response:
ERROR 1064: You have an error in your SQL syntax. Check the manual that
corresponds to your MySQL server version for the right syntax to use near 'select
User from mysql.db where Db='db_name')' at line 1
I also tried the command with = ANY instead of IN. I've run the same query on 4.1 and 5.0 versions of MySQL. Any help or insight on this is appreciated. Thanks
Ok, so it turns out I just didn't check the manual closely enough:
Starting with MySQL 4.1, all subquery forms and operations that the SQL standard requires are supported, as well as a few features that are MySQL-specific.
http://dev.mysql.com/doc/refman/4.1/en/subqueries.html