Sorry I am new to SQLPlus stuffs!
So here, I have a table called iowe, i have a four records pre-loaded into it. This is how it looks like:
NAME AMOUNT Serial Number
---------- ---------- -------------
Praveen 20500 1
Roshan 5000 2
Rohit 5000 3
Shashi 8000 4
Until I entered these four records, I did not know about the sequence function in SQL. So I tried implying it into this table. I wanted to input a new record, say "XXX" in name, 500 in Amount, and using the sequence command, i wanted the "Serial Number" to be auto incremented.
So I created a sequence called iowesqn, which looks like this, when i select * from user_sequences:
SEQUENCE_NAME MIN_VALUE MAX_VALUE INCREMENT_BY C O CACHE_SIZE LAST_NUMBER
------------------------------ ---------- ---------- ------------ - - ---------- -----------
SQN 1 5 2 N N 0 3
IOWESQN 1 1.0000E+27 1 N N 0 7
Please disregard the sequence SQN
To insert the sequence IOWESQN, I used this command: "insert into iowe(name, amount, "Serial Number")
values('XXX', 500, iowesqn.nextval)"
Everything works fine. The column Serial Number increments fine by 1 on every entry. However, when i try "insert into iowe ('&name', '&amount', "Serial Number") value(iowesqn.nextval));", it asks me fr the name, and the amount but right then (after the amount is input), it throws an error. It reads: "ORA-00928: missing SELECT keyword".
This is whole thing that comes up after the amount it input:
old 1: insert into iowe ('&name', '&amount', "Serial Number") value(iowesqn.nextval))
new 1: insert into iowe ('ret', 'ert', "Serial Number") value(iowesqn.nextval))
insert into iowe ('ret', 'ert', "Serial Number") value(iowesqn.nextval))
*
ERROR at line 1:
ORA-00928: missing SELECT keyword
Please tell me what I am (or (highly unlikely) it is) doing wrong.
Thanks in advance.
Your statement is wrong. Simple as that. With this fixed statement:
insert into iowe(name, amount, "Serial Number") values('XXX', 500, iowesqn.nextval)
You probably meant to replace your values by variables, not your fields?
insert into iowe(name, amount, "Serial Number") values('&name', &amount, iowesqn.nextval)
I just found another case where I get "missing SELECT keyword". I tried to insert with the column names in quotes, like this:
insert into subscription ('SUBSCRIPTION_ID','SUBSCRIPTION_NAME','CREATED_DATE') values ('558768','','20-JAN-20 10.37.47.901000000 PM');
Once I removed the quotes around the column names, it worked:
insert into subscription (SUBSCRIPTION_ID,SUBSCRIPTION_NAME,CREATED_DATE) values ('558768','','20-JAN-20 10.37.47.901000000 PM');
Other users may have been using value in stead of values. This is another case when you may face this problem.
This is because you have missed to mention the columns list
insert into table_name(1,'alskdjflasf')
it should be like this
insert into table_name (id,name)values(1.'lakjsdflasdf')
JUST ADD SINGLE QUOTES IN THE COLUMN NAMES
enter image description here
Related
I have customer data with mobile phone numbers where '1' has been entered 10 times or more in a cell to bypass the customer onboarding system validation. For example '1111111111'
I used below condition in my where clause but that didn't really help.
AND p.mobile_no LIKE '%[1111111111]%'
It is possible that users might enter 1 multiple number of times in the new customer form to bypass validation. To find only 0 values in the cell I used %[^0]% in the WHERE clause and I was hoping to use something similar to find 1s where regardless of how many times it has been entered in the field, as long as it only has 1 in it it will skim out the data for me.
How can I find these instances in my data using a SQL query?
The goal is to find these anomalies and remove them.
Using: Microsoft SQL Server 2016 (SP2).
I think you are looking for the following, which tests if at least 1 '1' exists, and that no other characters exist.
select Number
from (values ('111'),('121'),('1-2'),('22')) x (Number)
-- Test that at least 1 '1' exists
where Number like '%1%'
-- And that no other allowable characters exist - expand to cover all options
and Number not like '%[0,2-9,-]%'
Using a table to define invalid phone numbers:
Declare #invalidPhoneNumbers Table (PhoneNumber char(10));
Insert Into #testData (PhoneNumber)
Values ('0000000000'), ('1111111111'), ('2222222222'), ('3333333333'), ('4444444444')
, ('5555555555'), ('6666666666'), ('7777777777'), ('8888888888'), ('9999999999');
Select ...
From ...
Where ...
And p.mobile_no Not In (Select i.PhoneNumber From #invalidPhoneNumbers i)
Or - using NOT EXISTS which may perform better:
Declare #invalidPhoneNumbers Table (PhoneNumber char(10));
Insert Into #testData (PhoneNumber)
Values ('0000000000'), ('1111111111'), ('2222222222'), ('3333333333'), ('4444444444')
, ('5555555555'), ('6666666666'), ('7777777777'), ('8888888888'), ('9999999999');
Select ...
From ...
Where ...
And Not Exists (Select * From #invalidPhoneNumbers i Where i.PhoneNumber = p.mobile_no)
When declaring the table - make sure the data type defined matches exactly the defined data type of p.mobile_no. This will make sure there are no implicit conversions that can cause issues.
my column has customer numbers that are both numeric and combinations of text and numbers. I only want to convert them if they are all numeric otherwise leave them as a string
ex.
91036
ab321
10001
Only convert 91036 and 10001 as numbers (using cast or convert) but leave ab321 as string. I tried isnumeric but this isn't a recognized function in the query builder I'm using. And if I convert using cast or convert the strings are disappearing.
This is an example based on Oracle, but I believe that the same principle would work elsewhere (at least, in databases that support regular expressions).
I don't quite understand what you meant by saying that you want to "convert" those values to numbers; convert where? I presume that they are currently stored in a VARCHAR2 (or some other "character" datatype column). There's no use in converting them to number an leave them in the same column, as that wouldn't do absolutely anything - they would still be treated as strings (stored in the character datatype column, remember?).
So, I've created another - NUMBER datatype column and will populate it with a number whenever possible.
Sample data:
SQL> create table test (col_char varchar2(10),
2 col_num number);
Table created.
SQL> insert into test (col_char)
2 (select '91036' from dual union
3 select 'ab321' from dual union
4 select '10001' from dual
5 );
3 rows created.
Update uses REGEXP_LIKE function which checks whether COL_CHAR looks like a number:
^ anchors you to the beginning of the string
\d+ takes as many consecutive digits as it can find
$ anchors you to the end of the string
which, all together, means that string must begin with a digit, must end with a digit, and everything in between have to be digits.
SQL> update test set
2 col_num = to_number(col_char)
3 where regexp_like(col_char, '^\d+$');
2 rows updated.
SQL> select * From test;
COL_CHAR COL_NUM
---------- ----------
10001 10001
91036 91036
ab321
SQL>
Things are getting somewhat more complex when there are decimals and/or thousands separators in a string, so you might need to alter both TO_NUMBER function and regular expression pattern. For example:
SQL> update test set
2 col_num = to_number(col_char, '999990D00000', 'nls_numeric_characters = '',.''')
3 where regexp_like(col_char, '^[0-9]+|(\,)[0-9]+$');
2 rows updated.
SQL> select * from test;
COL_CHAR COL_NUM
---------- ----------
10001 10001
91,036 91,036
ab321
SQL>
I have a column in my Table i.e. TieBreaker which accepts only 4 digits Length value.
I have wrote a SQL SEQUENCE to generate a Series :
/* Snippet to DELETE Existing Sequence*/
IF EXISTS
(
SELECT * FROM Sys.Sequences WHERE Name = 'TieBreaker'
) DROP SEQUENCE TieBreaker
GO
/* Snippet to CREATE Sequence*/
CREATE SEQUENCE TieBreaker AS INT
START WITH 0000
INCREMENT BY 1
MINVALUE 0000
MAXVALUE 9999
CYCLE
GO
How can I output with Leading 0 for my sequence ? Like Below :
You do not. A number has no leading zeroes, as we all have learned in school.
The character formatting has. So you have 3 choices:
Make the field a varchar. This is not totally off as many number sequences also have prefixes and ARE NOT NUMBERS.
Add another computed field that formats the output so you can use that.
Do not care on database level but format in whatever program uses it.
An example of using a computed column for formatting
CREATE TABLE Test (
TieBreakerSeq INT DEFAULT NEXT VALUE FOR TieBreaker,
TieBreakerAsChar AS FORMAT(TieBreakerSeq, '0000#'),
SomeOtherData VARCHAR(10)
)
INSERT INTO Test (SomeOtherData) VALUES ('A'),('B'),('C')
SELECT * FROM Test
TieBreakerSeq TieBreakerAsChar SomeOtherData
------------- ---------------- -------------
0 00000 A
1 00001 B
2 00002 C
did u try
select lpad(TieBreaker.nextval,'4','0') from dual;
it would give same result right?
0000
0001
0002 and so on..
Query:
Select To_Number(qty) From my_table Where Id=12345;
Output:
ORA-01722: invalid number
01722. 00000 - "invalid number"
Query: Select qty From my_table Where Id=12345;
Output: 0.00080
Query:
Select To_Number(0.00080) From Dual;
Output:
0.00080 (no error)
This is a odd situation I am facing in Oracle. Can anybody suggest why it happens? The column qty is NUMBER type. Hence it is very hard to imagine that it contains invalid number, but it happened.
I want to clarify that it happened for the specific value in the column although we have thousands of records in the same column.
Added more: The same error appears if I use TO_CHAR(qty) function. The qty column is NUMBER type not VARCHAR2. In fact we are using SUM(qty) function which showed error. Hence I went for a dissection and found this row being the culprit.
I'm assuming that qty is defined as a varchar2 in my_table-- otherwise, there would be no purpose served by calling to_number. If that assumption is correct, I'll wager that there is some other row in the table where qty has non-numeric data in it.
SQL is a set-based language so Oracle (or any other database) is perfectly free to evaluate things in whatever order it sees fit. That means that Oracle is perfectly free to evaluate the to_number(qty) expression before applying the id=12345 predicate. If Oracle happens to encounter a row where the qty value cannot be converted to a number, it will throw an error.
It is also possible that there is some non-numeric data in the particular row where id = 12345 that happens not to be displaying (control characters for example). You can check that by running the query
SELECT dump(qty, 1016)
FROM my_table
WHERE id = 12345
(if you want decimal rather than hexadecimal, use 1010 as the second parameter to dump) and checking to see whether there is anything unexpected in the data.
The only way I can see you could get the results you've shown, given that qty really is a number field, is if it holds corrupt data (which is why there has been scepticism about that assumption). I'm also assuming your client is formatting the value with a leading zero, but is not forcing the trailing zero, which wouldn't normally appear; you can of course force it with to_char(.0008, '0.00000'), but you don't appear to be doing that; still, the leading zero makes me wonder.
Anyway, to demonstrate corruption you can force an invalid value into the field via PL/SQL - don't try this with real data or a table you care about:
create table t42(qty number);
table T42 created.
declare
n number;
begin
dbms_stats.convert_raw_value('bf0901', n);
insert into t42 (qty) values (n);
end;
/
anonymous block completed
select qty from t42;
QTY
----------
.00080
select to_number(qty) from t42;
Error starting at line : 12 in command -
select to_number(qty) from t42
Error report -
SQL Error: ORA-01722: invalid number
01722. 00000 - "invalid number"
Note the plain query shows the number as expected - though with a trailing zero, and no leading zero - and running it through to_number() throws ORA-01722. Apart from the leading zero, that is what you've shown.
It also fails with to_char(), as in your question title:
select to_char(qty) from t42;
Error starting at line : 13 in command -
select to_char(qty) from t42
Error report -
SQL Error: ORA-01722: invalid number
... which makes sense; your to_number() is doing an implicit conversion, so it's really to_number(to_char(qty)), and it's the implicit to_char() that actually generates the error, I think.
Your comments suggest you have a process that is loading and removing data. It would be interesting to see exactly what that is doing, and if it could be introducing corruption. This sort of effect can be achieved through OCI as the database will trust that the data it's passed is valid, as it does in the PL/SQL example above. There are bug reports suggesting imp can also cause corruption. So the details of your load process might be important, as might the exact database version and platform.
I encountered the nearly same problem. And I found the mysterious number behaved differently from the normal number after dump(). For example, assuming my qty=500 (datatype: number(30,2)) , then:
select dump(qty) from my_table where Id=12345;
Typ=2 Len=3: 194,6,1
select dump(500.00) from dual;
Typ=2 Len=2: 194,6
If we know how number datatype be stored (if not, plz visit http://translate.google.com/translate?langpair=zh-CN%7Cen&hl=zh-CN&ie=UTF8&u=http%3A//www.eygle.com/archives/2005/12/how_oracle_stor.html ) , we can find that there is a tailing zero (the last extra "1" in Typ=2 Len=3: 194,6,1) in the mysterious number.
So I made a trick to eliminate the tailing zero, and it works for the problem.
select dump(trunc(qty+0.001,2)) from my_table where Id=12345;
Typ=2 Len=2: 194,6
Hope someone to explain the deep mechanism.
try this:
Select To_Number(trim(qty)) From my_table Where Id=12345;
SQL> desc FLIGHTS;
Name Null? Type
----------------------------------------- -------- ----------------------------
FLNO NUMBER(38)
FROM VARCHAR2(64)
TO VARCHAR2(64)
DISTANCE NUMBER(38)
DEPARTS DATE
ARRIVES DATE
PRICE FLOAT(63)
data file:
99,Los Angeles,Washington D.C.,2308,2005/04/12 09:30,2005/04/12 21:40,235.98
13,Los Angeles,Chicago,1749,2005/04/12 08:45,2005/04/12 20:45,220.98
346,Los Angeles,Dallas,1251,2005/04/12 11:50,2005/04/12 19:05,225.43
387,Los Angeles,Boston,2606,2005/04/12 07:03,2005/04/12 17:03,261.56
and sqlldr control file:
LOAD DATA INFILE 'flights.txt'
INTO TABLE Flights
FIELDS TERMINATED BY ","
( FLNO
, FROM
, TO
, DISTANCE
, DEPARTS
, ARRIVES
, PRICE)
An exerpt from the error log:
Table FLIGHTS, loaded from every logical record.
Insert option in effect for this table: INSERT
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
FLNO FIRST * , CHARACTER
FROM NEXT * , CHARACTER
TO NEXT * , CHARACTER
DISTANCE NEXT * , CHARACTER
DEPARTS NEXT * , CHARACTER
ARRIVES NEXT * , CHARACTER
PRICE NEXT * , CHARACTER
Record 1: Rejected - Error on table FLIGHTS, column FROM.
ORA-01747: invalid user.table.column, table.column, or column specification
I am not sure what is wrong with my SQL, but I'm assuming it is because of the FROM entry?
Firstly, calling columns from and to is a bad idea, they're key-words. Something like origin and destination might be better...
Secondly, float, this really isn't needed. The chances of you needing a price to 63 decimal places is remote. Something like number(18,2) should be more than sufficient (ridiculous in fact), but if you want the absolute maximum use number(38,2).
My last pre-answer point is your datafile. If at all possible get your supplier to change this. A comma delimited file is just asking for trouble... there are far too many ways for a comma to be in the data. If you can have it | or ¬ delimited it's better as they're hardly ever used in text.
Depending on your NLS_PARAMETERS, there's no guarantee that the date in the file will be altered into the date you need in your table. It's best to explicitly specify this on entry into the database like this:
LOAD DATA
INFILE 'flights.txt'
INTO TABLE Flights
FIELDS TERMINATED BY ","
( FLNO
, FROM
, TO
, DISTANCE
, DEPARTS "to_date(:departs,'yyyy/mm/dd hh24:mi')"
, ARRIVES "to_date(:arrives,'yyyy/mm/dd hh24:mi')"
, PRICE DECIMAL EXTERNAL
)
Notice that I've also changed PRICE into a decimal, if you look at your log file, everything is supposedly a character, which means you're doing an implicit conversion, which may not be guaranteed.
Why you got your specific error message? I don't actually know. I also suspect it's because you've got a column called FROM. According to the control file documentation there's no SQL*Loader keyword from, so I can only posit that it's some problem with SQL*Loader's communication with Oracle.
Here's another good resource on syntax.