Oracle - Can't use * sign with other column in select clause - oracle

Sorry if it's trivial, but selecting column with * sign isn't working always, and I don't find reference to this behavior.
I can select table A and column col with the following statements:
select * from A; and select col from A; and select aa.col,aa.* from A aa;
But I can't view it together:
select *,col from A;
Will result in error ORA-00923: FROM keyword not found
select col,* from A aa;
Will result in error ORA-00936: missing expression
Why i must use the alias for * sign ?
select col,aa.* from A aa;
Why are the errors so misleading?

The restriction is not so clearly stated in documentation, but you can find it by following this diagram.
Here you see that if you use the *, you can't use anything else in select list

The syntax diagram for select shows:
The outermost path of that shows the plain, unprefixed * all-column wildcard on its own, and there is no loop back around for additional column expressions - all paths with a comma (to separate terms) are distinct from that plain * path.
On the inner path that does allow a comma, and thus multiple expressions, you can only use .* prefixed by a table/view/alias, and can then follow (or precede) that with other expressions.
(I really thought that was stated more clearly somewhere, but I can't find it anywhere in recent documentation...)
Why i must use the alias for * sign ?
select col,aa.* from A aa;
That isn't quite accurate; you don't have to use an alias, you can use the table name directly if it isn't aliased, so this is also valid:
select col,A.* from A;
There is a school of thought that you shouldn't use a wildcard anyway, at least for anything except an ad hoc query - it's better to list all of the required column name explicitly, prefixed with the appropriate table name/alias particularly if there is a join, for clarity and to avoid unexpected issues with tables being modified. That's rather outside the scope of this question though *8-)

Why are the errors so misleading?
The errors are correct. They just don't guess what you are trying to do. After
select *
the next keyword should be from, so anything else gives
FROM keyword not found where expected
After , there should be a valid expression such as a column name, not * which is unexpected, so you get
ORA-00936: missing expression
Perhaps it would be nice if Oracle wrote a special error message about the incorrect use of *, but so far they have not. You could propose it on the Oracle Database Ideas forum.

Related

Updating oracle records that starts with special char

I have below table dim_ethernet which has a column 5G_ON_AIR_DT
. I have to update its value from programming so I have written syntax in below style .
I got an error while running the code.
Does any one know how to write this code properly.
update ORA.dim_ethernet
set "5G_ON_AIR_DT" =: 5G_ON_AIR_DT
WHERE SITE_DWKEY =: SITE_DWKEY;
Seems like you are very new to Oracle world. Couple of things that are worth considering.
Your Query:
update ORA.dim_ethernet
set "5G_ON_AIR_DT" =: 5G_ON_AIR_DT
WHERE SITE_DWKEY =: SITE_DWKEY;
Points:
=: makes no sense as it is not valid in either SQL or PLSQL.
:= is an assignment operator in PLSQL.
= is assignment operator in SQL
PLSQL and SQL are two different engines but work together flawlessly giving an impression that they are one and the same. But in fact, they are not.
:some_val acts as a bind variable.
Using "column_name" is bad. Objects in Oracle are not case sensitive and if you put any object name inside double quotes, then it becomes case sensitive. There is no need to make your column name case sensitive.
That said, post the sample data and expected output. You will receive the best replies on the forum to handle what you are doing.
You have an identifier 5G_ON_AIR_DT.
From the Database Object Names and Qualifiers documentation:
Nonquoted identifiers must begin with an alphabetic character from your database character set. Quoted identifiers can begin with any character.
Since your identifier does not begin with an alphabetic character it cannot be used as a non-quoted identifier and always must be used with quotes.
You also have syntax errors with the =: and should be using = instead.
This would give you the query:
UPDATE ORA.dim_ethernet
SET "5G_ON_AIR_DT" = "5G_ON_AIR_DT"
WHERE SITE_DWKEY = SITE_DWKEY;
(Note: this statement will update the rows where SITE_DWKEY is not NULL and modify the 5G_ON_AIR_DT column to be its current value; so appears to be a pointless operation but would now be syntactically valid.)
db<>fiddle here

Why does "UPDATE Users SET Password=? WHERE Username=?" give a syntax error? [duplicate]

One of my columns is called from. I can't change the name because I didn't make it.
Am I allowed to do something like SELECT from FROM TableName or is there a special syntax to avoid the SQL Server being confused?
Wrap the column name in brackets like so, from becomes [from].
select [from] from table;
It is also possible to use the following (useful when querying multiple tables):
select table.[from] from table;
If it had been in PostgreSQL, use double quotes around the name, like:
select "from" from "table";
Note: Internally PostgreSQL automatically converts all unquoted commands and parameters to lower case. That have the effect that commands and identifiers aren't case sensitive. sEleCt * from tAblE; is interpreted as select * from table;. However, parameters inside double quotes are used as is, and therefore ARE case sensitive: select * from "table"; and select * from "Table"; gets the result from two different tables.
These are the two ways to do it:
Use back quote as here:
SELECT `from` FROM TableName
You can mention with table name as:
SELECT TableName.from FROM TableName
While you are doing it - alias it as something else (or better yet, use a view or an SP and deprecate the old direct access method).
SELECT [from] AS TransferFrom -- Or something else more suitable
FROM TableName
Your question seems to be well answered here, but I just want to add one more comment to this subject.
Those designing the database should be well aware of the reserved keywords and avoid using them. If you discover someone using it, inform them about it (in a polite way). The keyword here is reserved word.
More information:
"Reserved keywords should not be used
as object names. Databases upgraded
from earlier versions of SQL Server
may contain identifiers that include
words not reserved in the earlier
version, but that are reserved words
for the current version of SQL Server.
You can refer to the object by using
delimited identifiers until the name
can be changed."
http://msdn.microsoft.com/en-us/library/ms176027.aspx
and
"If your database does contain names
that match reserved keywords, you must
use delimited identifiers when you
refer to those objects. For more
information, see Identifiers (DMX)."
http://msdn.microsoft.com/en-us/library/ms132178.aspx
In Apache Drill, use backquotes:
select `from` from table;
If you ARE using SQL Server, you can just simply wrap the square brackets around the column or table name.
select [select]
from [table]
I have also faced this issue.
And the solution for this is to put [Column_Name] like this in the query.
string query= "Select [Name],[Email] from Person";
So it will work perfectly well.
Hi I work on Teradata systems that is completely ANSI compliant. Use double quotes " " to name such columns.
E.g. type is a SQL reserved keyword, and when used within quotes, type is treated as a user specified name.
See below code example:
CREATE TABLE alpha1
AS
(
SEL
product1
type_of_product AS "type"
FROM beta1
) WITH DATA
PRIMARY INDEX (product1)
--type is a SQL reserved keyword
TYPE
--see? now to retrieve the column you would use:
SEL "type" FROM alpha1
I ran in the same issue when trying to update a column which name was a keyword. The solution above didn't help me. I solved it out by simply specifying the name of the table like this:
UPDATE `survey`
SET survey.values='yes,no'
WHERE (question='Did you agree?')
The following will work perfectly:
SELECT DISTINCT table.from AS a FROM table
Some solid answers—but the most-upvoted one is parochial, only dealing with SQL Server. In summary:
If you have source control, the best solution is to stick to the rules, and avoid using reserved words. This list has been around for ages, and covers most of the peculiarities. One tip is that reserved words are rarely plural—so you're usually safe using plural names. Exceptions are DIAGNOSTICS, SCHEMAS, OCTETS, OFFSETS, OPTIONS, VALUES, PARAMETERS, PRIVILEGES and also verb-like words that also appear plural: OVERLAPS, READS, RETURNS, TRANSFORMS.
Many of us don't have the luxury of changing the field names. There, you'll need to know the details of the RDBM you're accessing:
For SQL Server use [square_braces] around the name. This works in an ODBC connection too.
For MySQL use `back_ticks`.
Postgres, Oracle and several other RDBMs will apparently allow "double_quotes" to be used.
Dotting the offending word onto the table name may also work.
You can put your column name in bracket like:
Select [from] from < ur_tablename>
Or
Put in a temprary table then use as you like.
Example:
Declare #temp_table table(temp_from varchar(max))
Insert into #temp_table
Select * from your_tablename
Here I just assume that your_tablename contains only one column (i.e. from).
In MySQL, alternatively to using back quotes (`), you can use the UI to alter column names. Right click the table > Alter table > Edit the column name that contains sql keyword > Commit.
select [from] from <table>
As a note, the above does not work in MySQL
Judging from the answers here and my own experience. The only acceptable answer, if you're planning on being portable is don't use SQL keywords for table, column, or other names.
All these answers work in the various databases but apparently a lot don't support the ANSI solution.
Simple solution
Lets say the column name is from ; So the column name in query can be referred by table alias
Select * from user u where u.from="US"
In Oracle SQL Developer, pl/sql you can do this with double quotes but if you use double quotes you must type the column names in upper case. For example, SELECT "FROM" FROM MY_TABLE

How to identify column types during sql injection?

Situation is following:
I have identified sql injection attack vector, and have following information about target table:
It has six columns. (Identified using "order by").
I can see output of 3 of them (table is displayed). two seems kind of enum value (integer in database?), and one is a date. I have very strong suspicion that col #6 is date column.
I'm almost sure the database is oracle. (ROWNUM works and LIMIT gives error).
I don't have error messages (always generic text is returned - "something went wrong").
Frontend is PHP if that matters. But there might be middle layer between it and database (e.g. java service), so I'm not sure where the query is being constructed.
E.g. following search query works as expected:
test' AND ROWNUM <= 5 ORDER BY 6--
EDIT-FROM-HERE:
Ok after help from comments, following query works:
test' UNION ALL SELECT null,null,null,null,null,null FROM dual--
(I was missing FROM dual part. Thank you #kordirko very much!)
This query adds one empty record in the output table (it is visually visible), so I'm definitely on the right track!
Now following line also works:
test' UNION ALL SELECT null,null,null,n't',null,null FROM dual--
I correctly identified 4th column and now it displays uppercase(?) letter T where I expected it to appear. So far so good. But it gives error when I input any string longer than 1 char! So following gives an error:
test' UNION ALL SELECT null,null,null,n'test',null,null FROM dual--
I'm no expert in SQL injection, and especially ORACLE (though have experience with MsSql).
I think the problem is something unicode-ansi-whateverencoding-related. For other rows (selected by original query before my UNION ALL SELECT addition) the 4th column gives multi-character normal strings. But when I try to inject desired string, it only works if it's one character, and also misteriously displays it in uppercase. I think this must be some encoding problem. I just discovered I needed n prefix for unicode string after 1 hour of searching and struggling. Maybe some Oracle gurus can quickly spot what mistake do I have in my query?

SELECT Roughly equals

I am transfering from access to oracle and couldn't find a roughly equals function in oracle. Does such a thing exist?
I am referring to something like:
SELECT * FROM Table WHERE name ='*nswer is thi*';
Use LIKE:
SELECT * FROM Table WHERE name LIKE '%nswer is thi%';
Explanation:
This query will select records which contains "nswer is thi" anywhere in the field name.
For example:
name
--------------------
answer is this
blahnswer is thiblah
The LIKE conditions specify a test involving pattern matching. Whereas the equality operator (=) exactly matches one character value to another
Read more here.

Named Parameter with AND/OR in CONTAINS query is not working

I am using Oracle Text for searching in my web application. I have configured Oracle Text by creating Data Store and Index.
This is my query
select * from PROFILE where CONTAINS(FIRST_NAME,:firstName OR :secondName,1)>0;
Every time I get the following exception ORA-00907: missing right parenthesis.
But after replacing :firstName and :secondName by any string it's working perfectly.
Also its working perfectly with one parameter.
select * from PROFILE where contains(FIRST_NAME,:firstName,1)>0
The above code is working. But after adding OR :secondName, the result is ORA-00907
From the Oracle Text documentation, it seems CONTAINS is a defined as a regular function with three parameters (the last one optional):
CONTAINS(
[schema.]column,
text_query [VARCHAR2|CLOB]
[,label NUMBER])
RETURN NUMBER;
The text_query parameter is a regular string interpreted as a phrase. Thus you should write:
select * from PROFILE where contains(FIRST_NAME, :search_query, 1)>0
And bind the value FOO OR BAR to the variable search_query since the OR keyword is not part of the SQL query in this case.
You should better use
select * from PROFILE where CONTAINS(FIRST_NAME,:firstName ,1)>0
OR CONTAINS(FIRST_NAME,:secondName,1)>0

Resources