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
Related
I am trying to code a sqlldr.ctl file WHEN Clause to limit the records imported to those matching a portion of the current Schema's name.
The code I have (which does NOT work) is:
LOAD DATA
TRUNCATE INTO TABLE TMP_PRIM_ACCTS
when REGION_NUM = substr(user,-3,3)
Fields terminated by "|" Optionally enclosed by '"'
Trailing NULLCOLS
( PORTFOLIO_ACCT,
PRIMARY_ACCT_ID NULLIF (PRIMARY_ASSET_ID="NULL"),
REGION_NUM NULLIF (PARTITION_NUM="NULL")
)
sqlldr returns:
SQL*Loader-350: Syntax error at line 3.
Expecting quoted string or hex identifier, found "substr".
when PARTITION_NUM = substr(user,-3,3)
I cannot put single quotes around "user", because that turns it into the literal string "user". Can anyone explain how I can reference the "active" User in this WHEN Clause?
Thank you!
Can you try something like this? (now I can't make test with SQLLDR, but this is syntax I used for changing values):
when REGION_NUM = "substr(:user,-3,3)"
It doesn't look like you can. The documentation only shows fixed values:
Trying to use an expression in when that clause (or in nullif; thought I'd try to see if you could cause a rejection based on null PK value) you just see the literal value in the log:
Table TMP_PRIM_ACCTS, loaded when REGION_NUM = 0X73756273747228757365722c2d332c3329(character 'substr(user,-3,3)')
which is sort of what you referred when you said you couldn't quote user, but you'd have to quite the whole thing anyway. Using :user doesn't work either, the colon is seen as just another character, it doesn't try to find a column called user instead.
The simplest approach may be to pre-process the data file and remove any rows which don't match the pattern (e.g. via a regex). That would actually be slightly easier if you used an external table instead of SQL*Loader.
Alternatively, generate your control file and embed the correct literal value based on the user you'll connect as.
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
I have a little silly question. I have installed a PostgreSQL DB Server, but when I run query, there is a problem with column identifier without quotes. I don't know why the quotes around identifiers are needed. My query:
SELECT vc."CAR_ID"
FROM "VEL_CAR" vc, "VEL_DRIVER" vd, "VEL_DRIVER_CAR" vdc
WHERE vc."CAR_ID" = vdc."CAR_ID" and
vdc."DRIVER_ID" = vd."DRIVER_ID";
My practice from Oracle DB is not to use ". So in Oracle:
SELECT vc.CAR_ID
FROM VEL_CAR vc, VEL_DRIVER vd, VEL_DRIVER_CAR vdc
WHERE vc.CAR_ID = vdc.CAR_ID and
vdc.DRIVER_ID = vd.DRIVER_ID;
When I run this query without quotes in PostgreSQL it throws error about syntax:
ERROR: column vc.car_id does not exist
LINE 1: SELECT vc.CAR_ID
Do you know why?
--SOLVED--
Thank you, now I solved the problem! It was about table creation. I created table objects using pgAdminIII and i wrote table name and column names uppercased. pgAdminIII created query with quotas - because of the names was uppercased. So query had to be written with quotas.
When you create your tables using double quotes, column and table names become case sensitive. So "car_id" is a different name than "CAR_ID"
You need to create your tables without using double quotes, then the names are not case sensitive: car_id is the same as CAR_ID (note the missing quotes!)
See the manual for details:
http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
Edit:
Oracle behaves just the same way. The only difference is that Oracle stores names in upper case and Postgres stores them in lower case. But the behaviour when using quotes is identical.
From Postgres documentation :
Quoting an identifier also makes it case-sensitive, whereas unquoted names are always folded to lower case. For example, the identifiers FOO, foo, and "foo" are considered the same by PostgreSQL, but "Foo" and "FOO" are different from these three and each other. (The folding of unquoted names to lower case in PostgreSQL is incompatible with the SQL standard, which says that unquoted names should be folded to upper case. Thus, foo should be equivalent to "FOO" not "foo" according to the standard. If you want to write portable applications you are advised to always quote a particular name or never quote it.)
Seems to me that the table vc does not have a column named car_id. Are you sure it is there? Do \d vel_car to see the structure of the table.
The quotes are optional and you can usually skip them.
I have a query that has
... WHERE PRT_STATUS='ONT' ...
The prt_status field is defined as CHAR(5) though. So it's always padded with spaces. The query matches nothing as the result. To make this query work I have to do
... WHERE rtrim(PRT_STATUS)='ONT'
which does work.
That's annoying.
At the same time, a couple of pure-java DBMS clients (Oracle SQLDeveloper and AquaStudio) I have do NOT have a problem with the first query, they return the correct result. TOAD has no problem either.
I presume they simply put the connection into some compatibility mode (e.g. ANSI), so the Oracle knows that CHAR(5) expected to be compared with no respect to trailing characters.
How can I do it with Connection objects I get in my application?
UPDATE I cannot change the database schema.
SOLUTION It was indeed the way Oracle compares fields with passed in parameters.
When bind is done, the string is passed via PreparedStatement.setString(), which sets type to VARCHAR, and thus Oracle uses unpadded comparision -- and fails.
I tried to use setObject(n,str,Types.CHAR). Fails. Decompilation shows that Oracle ignores CHAR and passes it in as a VARCHAR again.
The variant that finally works is
setObject(n,str,OracleTypes.FIXED_CHAR);
It makes the code not portable though.
The UI clients succeed for a different reason -- they use character literals, not binding. When I type PRT_STATUS='ONT', 'ONT' is a literal, and as such compared using padded way.
Note that Oracle compares CHAR values using blank-padded comparison semantics.
From Datatype Comparison Rules,
Oracle uses blank-padded comparison
semantics only when both values in the
comparison are either expressions of
datatype CHAR, NCHAR, text literals,
or values returned by the USER
function.
In your example, is 'ONT' passed as a bind parameter, or is it built into the query textually, as you illustrated? If a bind parameter, then make sure that it is bound as type CHAR. Otherwise, verify the client library version used, as really old versions of Oracle (e.g. v6) will have different comparison semantics for CHAR.
If you cannot change your database table, you can modify your query.
Some alternatives for RTRIM:
.. WHERE PRT_STATUS like 'ONT%' ...
.. WHERE PRT_STATUS = 'ONT ' ... -- 2 white spaces behind T
.. WHERE PRT_STATUS = rpad('ONT',5,' ') ...
I would change CHAR(5) column into varchar2(5) in db.
You can use cast to char operation in your query:
... WHERE PRT_STATUS=cast('ONT' as char(5))
Or in more generic JDBC way:
... WHERE PRT_STATUS=cast(? as char(5))
And then in your JDBC code do use statement.setString(1, "ONT");
Ok, this is bit of an obscure question, but hopefully someone can help me out with it.
The system I'm working on builds a dynamic SQL string for execution inside a stored procedure, and part of that dynamic SQL defining column aliases, which themselves are actually values retrieved from another table of user generated data.
So, for example, the string might look something like;
SELECT table1.Col1 AS "This is an alias" FROM table1
This works fine. However, the value that is used for the alias can potentially contain a double quote character, which breaks the outer quotes. I thought that I could maybe escape double quotes inside the alias somehow, but I've had no luck figuring out how to do so. Backslash doesn't work, and using two double quotes in a row results in this error;
SQL Error: ORA-03001: unimplemented feature
03001. 00000 - "unimplemented feature"
*Cause: This feature is not implemented.
Has anyone had any experience with this issue before?
Cheers for any insight anyone has.
p.s. the quotes are needed around the aliases because they can contain spaces.
Can you just put another character instead of double quotes and replace that with double quotes in the code?
Something like this:
SELECT table1.Col1 AS "This is |not| an alias" FROM table1
Then just replace | with ".
I know it's a hack, but I can't think of any better solution... And what you are doing there is a hack anyway. The "nice" way would be to select the values and the column names separately and associate them in your code. That would make things much cleaner.
use the Oracle quote operator:
select q'#someone's quote#' from dual;
the '#' can be replaced by any character
When I run this:
select 'test"columnname"' from dual
Oracle returns this (notice the Oracle-generated column name):
'TESTCOLUMNNAME'
--------------------------------
test"columnname
The fact that Oracle's column name doesn't include my double-quote tells me that Oracle probably cannot represent that.
Best bet as far as I can see is to strip double-quotes from your data prior to using column names. Sadly, that will also require that you do the same filtering when you select those columns, but I don't see another way.
a possibly fruitful area of investigation would be to look into the quote method.
my $quotedString = $dbh->quote( $string );
Try this, two single quotes actually look like one double quote in output:
select 1 as "University ''John Smith''" from dual;