Validate PL/SQL without permanent changes in database - sql

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

Related

How would a ORA-00923: FROM keyword not found where expected be vulnerable to SQL Injection?

Suppose I have a web application. I do not know the backend. I submit some forms, and finally, end up at a error message.
It states:
ORA--0923: FROM keyword not found where expected.
So, we know that this means that the developer programmed something similar to this:
SELECT *
employees;
which is missing a from keyword, or it's not where it's expected.
So now that you have the query
SELECT * employees;
Theoretically how would you inject this?
For sql injection to be possible, the query would have to have parameters or bind variables being passed to it from the web interface. This query is syntactically incorrect without any parameters. The only way that this query could be involved in a sql injection scenario would be if the web application accepted the entire query and then executed it.
Say the database is trying to execute a simple statement like
select 'smith' from dual;
The developer has, instead of using a bind variable, concatenated the string 'smith' (with quotes) into a statement
A hacker then tries a name with a single quote in it
select 'o'reilly' from dual;
That breaks the app with the error
ORA-01756: quoted string not properly terminated
They then try the string ' where 1=1' which gets converted to the statement
select '' where 1=1'' from dual;
which errors with
ORA-00923: FROM keyword not found where expected
There are other keywords (eg ORDER BY) that would give the same error, so it is possible you've stumbled across one.
Generally that should be sufficient for a bug report.

How to execute a pre-defined query having parameters (i.e. a PARAMETERS declaration) in a Microsoft Access database over ODBC?

My simple question is as follows:
If I have a Microsoft Access database with a defined "query" in it (i.e. the kind of database object that MS Access calls a Query, just to avoid any ambiguity) defined to take parameters (using a PARAMETERS declaration inside its SQL definition) what is the correct SQL syntax to call it over an ODBC connection, including providing the parameter values?
EDIT / ADDITION:
I just noticed that it could be done by adding curly-braces around the entire CALL command, as follows:
{CALL myAccessQuery ('string1', 'string2', 'string3')}
This was actually exactly what they already did in the other related SO thread that I'm referring to here below, but I just thought that this was some C#-specific magic related to the prepared-statement nature of their SQL statement (using "?" in it), or some other peculiarity of their SQL library (I'm not using that language), so I previously ignored it.
Anyone who will explain what the curly-braces are, and why they allow for execution of more SQL commands than the explicitly stated supported ones in the error message below, will be an accepted answer for this question.
Some more details for my specific case:
My query takes three parameters, defined by a "PARAMETERS" clause in the beginning of the query's declaration, as so:
PARAMETERS myParam1 Text ( 255 ), myParam2 Text ( 255 ), myParam3 Text ( 255 );
SELECT ... <a bunch of not relevant stuff here> ;
Using an (already established and confirmed working) ODBC connection, I want to use this query from an external application, including providing the required three parameters for it.
Running normal queries like SELECT etc works just fine over the connection from my external application, but no matter how much I google, I cannot seem to find out the proper way to correctly provide the parameters for and run my query? So, again, my question is, what is the correct SQL syntax for doing this?
NOTE: I do NOT want any API specific solution for some certain library or similar, since this only solves the problem for a very small part of all developers who want to do this from different programming languages, so for this reason, I won't even bring up what language my external application is written in. I just want the full SQL syntax for doing this, nothing more, nothing less.
Another SO question indicates that this should be done using the "CALL" keyword, but when I try to use this from my application, I just get the following error message:
[42000] [Microsoft][ODBC Microsoft Access Driver] Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'.
I.e., this is the "SQL command" (purposely avoiding the ambiguous term "query"...) that I'm trying to execute when getting this error:
CALL myAccessQuery ('string1', 'string2', 'string3')
The only one of the SQL keywords mentioned in the error message that seem likely to be useful is the "PROCEDURE" keyword, but I'm having similarly big difficulties finding any relevant documentation also for this on Google. :-(
I suspect that most of Google's lack of results in regards to this entire scenario comes from the many involved ambiguities regarding more or less all the central keywords in the context, like "queries", "parameters", "execute", "call" and "procedure", so with this SO question my hope is that it will constitute a somewhat more easily identified and indexed answer for this question to be presented by Google in the future.
When you're connecting over ODBC, look at the driver-specific information to see if it supports the various ODBC extensions (indicated by curly braces in the ODBC calls):
https://msdn.microsoft.com/en-us/library/ms675326(v=vs.85).aspx
Specifically:
ODBC provides a specific syntax for calling stored procedures. For the CommandText property of a Command object, the CommandText argument to the Execute method on a Connection object, or the Source argument to the Open method on a Recordset object, passes in a string with this syntax:
"{ [ ? = ] call procedure [ ( ? [, ? [ , … ]] ) ] }"
Each ? references an object in the Parameters collection. The first ? references Parameters(0), the next ? references Parameters(1), and so on.
The parameter references are optional and depend on the structure of the stored procedure. If you want to call a stored procedure that defines no parameters, your string would look like the following:
"{ call procedure }"
The Access ODBC driver exposes saved SELECT parameter queries as Stored Procedures, so that's why you use this syntax.

visual studio 2012 query builder

Can anybody tell me what does the error mean? Whenever I open the query builder it will prompt with an error indicating that SQL syntax errors were encountered.
https://msdn.microsoft.com/en-us/library/ms189012.aspx
I looked at the following page in MSDN but I don't understand what it means...
For instance, what do these bullet points from the MSDN article mean?
The SQL statement is incomplete or contains one or more syntax errors.
The SQL statement is valid but is not supported in the graphical panes (for example, a Union query).
The SQL statement is valid but contains syntax specific to the data connection you are using.
USER (which you've apparently decided is an appropriate table name) is a SQL Server reserved word.
The best solution is to rename your table, so you don't have to escape the table name every time you want to query it and to make it clear it's your user data (hey, there's a table name suggestion - userdata).
The other option is to escape the name by surrounding it with square brackets:
SELECT * FROM [users]
Note that it will get old fast having to do this with every query. Again, the best solution would be to rename the table to something that isn't a reserved word.

Oracle SQL Developer: possible to pass parameters to SQL script?

I have the following SQL script (all names replaced with metasyntactic variables):
DELETE FROM FOO
WHERE UPPER(BAR)=? AND UPPER(BAZ)=? AND UPPER(QUX)=? AND UPPER(QUUX)=? AND UPPER(CORGE)=?;
When I run it in SQL Developer, I get the following error, as expected: SQL Error: Missing IN or OUT parameter at index:: 1
Is there a way in SQL Developer to pass test parameters to these values (in this case, BAR, BAZ, QUX, QUUX, and CORGE) or do I have to manually replace the question marks? Thanks!
UPDATE: I've been looking on the internet to try to find the answer with no luck; none of the articles I found deal with the FOO=? syntax. I know that that is the proper syntax to access (and in this case, delete from) the database from a Java program, but I would like to test the SQL script before embedding it in the program.
A query that way is called a prepared statement. It is used as a way to send SQL statements from a program to the database.
First you have to prepare the prepared statement object and later you supply the parameters and finally execute the statement. When setting the parameters, you refer to each question mark in the order they apear in the statement. So in you case, BAR would be parameter 1 and CORGE will be parameter 5.
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
For testing a query like this is quite useless in my experience. You could change the paramters to variables or even substitution variables if that is more convenient while testing.
http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch5.htm#i1211130

Can I prepare a statement in plain Oracle SQL?

3GLs provide mechanisms to prepare statements before executing them. E.g.
SELECT name
FROM people
WHERE age=:AGE
The same query can then be executed for different ages. But can such a statement also be prepared in a "plain" Oracle SQL client? Can the same be done in e.g. SQL Plus or dbForge Studio for Oracle as in Java or C# or any other programming language that supports prepared statements?
In dbForge Studio for Oracle, named parameters can be used, preceded by a colon :
SELECT *
FROM people
WHERE name=:name
The parameters can then be filled in with the "Edit parameters dialog box", available from the SQL toolbar.
I know you didn't ask about PostgreSQL but about Oracle. However, of note, PostgreSQL has this feature right in its SQL language.
The SQL standard includes a PREPARE statement, but it is only for use in embedded SQL. The PostgreSQL version of the PREPARE statement works like this:
PREPARE nameByAge(number) AS
SELECT name
FROM People
WHERE age=$1;
and you use it like this:
EXECUTE nameByAge(18);
EXECUTE nameByAge(50);
So unfortunately for Oracle SQLPlus the answer seems to be no, not bind variables. But SQLPlus has substitution variables, similar to shell scripts. You use them as &1, &2, &3, ... and they get their parameters from the way you call the SQLPlus script.
sqlplus user/password #script.sql 18
sqlplus user/password #script.sql 50
with the script.sql being
SELECT name
FROM People
WHERE age=&1;
this would work, even though it is not bind. But then, do you really care about the slight savings in repeat parse time? In fact Oracle hashes SQL statements and already replaces constants with bind variables to be able to better reuse query plans. So the savings you would get with PREPARE and BIND are really minuscule.