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
Related
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
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.
I have an oracle query which has a select statement
select table.columnname = ${sometext_sometext_sometext}
I would like to know what is the purpose of ${}.
Also this throws an error in Oracle SQL developer. Kindly advise what is the work around.
This isn't Oracle syntax, this is a common syntax for interpolating variables into a string found in Perl, Groovy, and a bunch of other languages.
You don't say what the context is here, but what is probably going on is something modifies the file, probably with environment-related properties, before the SQL gets run, the ${} is there to identify to the modifying script what value to substitute here. This is a common thing to do when you have environment-specific properties that need to be injected into a SQL script.
Can you give some background as to where you got this SQL statement? It appears that you are working with a query that requires pre-processing via Java, PHP, a Bash shell script, etc. Standard Oracle SQL or PL/SQL does not know what to do with the "${}" syntax.
I have used this syntax in a standard SQL template that I then process in Java or a bash shell script to generate the final SQL statement.
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.
I'm getting a little confused about using parameters with SQL queries, and seeing some things that I can't immediately explain, so I'm just after some background info at this point.
First, is there a standard format for parameter names in queries, or is this database/middleware dependent ? I've seen both this:-
DELETE * FROM #tablename
and...
DELETE * FROM :tablename
Second - where (typically) does the parameter replacement happen? Are parameters replaced/expanded before the query is sent to the database, or does the database receive params and query separately, and perform the expansion itself?
Just as background, I'm using the DevArt UniDAC toolkit from a C++Builder app to connect via ODBC to an Excel spreadsheet. I know this is almost pessimal in a few ways... (I'm trying to understand why a particular command works only when it doesn't use parameters)
With such data access libraries, like UniDAC or FireDAC, you can use macros. They allow you to use special markers (called macro) in the places of a SQL command, where parameter are disallowed. I dont know UniDAC API, but will provide a sample for FireDAC:
ADQuery1.SQL.Text := 'DELETE * FROM &tablename';
ADQuery1.MacroByName('tablename').AsRaw := 'MyTab';
ADQuery1.ExecSQL;
Second - where (typically) does the parameter replacement happen?
It doesn't. That's the whole point. Data elements in your query stay data items. Code elements stay code elements. The two never intersect, and thus there is never an opportunity for malicious data to be treated as code.
connect via ODBC to an Excel spreadsheet... I'm trying to understand why a particular command works only when it doesn't use parameters
Excel isn't really a database engine, but if it were, you still can't use a parameter for the name a table.
SQL parameters are sent to the database. The database performs the expansion itself. That allows the database to set up a query plan that will work for different values of the parameters.
Microsoft always uses #parname for parameters. Oracle uses :parname. Other databases are different.
No database I know of allows you to specify the table name as a parameter. You have to expand that client side, like:
command.CommandText = string.Format("DELETE FROM {0}", tableName);
P.S. A * is not allowed after a DELETE. After all, you can only delete whole rows, not a set of columns.