ORA-00917: missing comma when insert not exist in oracle - sql

I have query like this :
INSERT INTO KONTAK (IDKONTAK, NAMA, NOHP, ALAMAT, GROUPKONTAK_FK) VALUES
(SQ_IDKONTAK.NEXTVAL, 'ANDIKA PRATAMA', '+6285226202202', 'JPR', '' WHERE NOT EXISTS
(SELECT * FROM KONTAK WHERE NAMA = 'AMIN'))
I want insert data to KONTAK table based on the values where not exist in KONTAK NAMA='AMIN'.
When I ran it I got error :
ORA-00917: missing comma
Any suggestion?

If you are trying to do a conditional insert, then you can either use MERGE, or use something like this, assuming you want to insert 'ANDIKA PRATAMA' only if 'AMIN' is not already there (which doesn't make sense to me, but it seems to be your goal):
insert into table1(id1, col1, col2)
select sequence1.nextval, 'VAL1', 'VAL2'
from dual
where not exists (select 1 from table1 where col1 = 'AMIN')
http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9014.htm

Use Where condition in insert with select statement;
try;
INSERT INTO KONTAK (IDKONTAK, NAMA, NOHP, ALAMAT, GROUPKONTAK_FK)
select
SQ_IDKONTAK.NEXTVAL, 'ANDIKA PRATAMA', '+6285226202202', 'JPR', ''
from dual
WHERE NOT EXISTS (
SELECT * FROM KONTAK WHERE NAMA = 'AMIN'
)

Related

How to insert query result into existing table in Google's BigQuery using SQL statement?

I have a huge_query_that_runs_fine_alone that starts with select.
I want to insert that query result into existing table, but usual SQL statements no work.
I tried: insert into test_ds.test_tbl (field1, …, fieldN) values (huge_query_that_runs_fine_alone), but query editor says me that select keyword in unexpected place;
And this: select * into test_ds.test_tbl from (huge_query_that_runs_fine_alone), but query editor says me this Syntax error: Unexpected keyword INTO at [1:10];
What to do?
P.S. Full query...
insert into test_bq_dataset.test_tbl (Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo, AmountPromo, SumPromo, AmountNoPromo, SumNoPromo) values (select promos.Naimenovanie_SKU, promos.Naimenovanie_TT, promos.MonthNo, promos.YearNo, AmountPromo, SumPromo, AmountNoPromo, SumNoPromo from
(select Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo, sum(Prodazhi_Litry) as AmountPromo, sum(Prodazhi_Summa_s_NDS) as SumPromo from IACloud0539_Calc.Data2_PROMO where Promo = false group by Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo) promos
left join
(select Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo, sum(Prodazhi_Litry) as AmountNoPromo, sum(Prodazhi_Summa_s_NDS) as SumNoPromo from IACloud0539_Calc.Data2_PROMO where Promo = true group by Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo) nopromos
on
promos.Naimenovanie_SKU = nopromos.Naimenovanie_SKU
and
promos.Naimenovanie_TT = nopromos.Naimenovanie_TT
and
promos.MonthNo = nopromos.MonthNo
and
promos.YearNo = nopromos.YearNo);
Syntax error: Unexpected keyword SELECT at [1:149]
You could just place a SELECT query below the INSERT clause and it'll work just fine
ex:
CREATE TABLE temp.mytest5 (col1 STRING, col2 STRING);
And the insertion:
INSERT INTO temp.mytest5 (col1, col2)
SELECT 'record1', 'record2'

SQL bullk inserts if records do not exist

As part of my build I am changing some .sql files. As it is now, the queries delete particular records from the table and re-add them during the install. What we'd like to have is a check, to see if certain records exist. If they are, do nothing, but if they aren't perform ~30 inserts.
Again these are .sql files and I can't seem to get the syntax right. I think it should be
IF (SELECT COUNT(*) FROM foo WHERE x = bar) <= 0
THEN
BEGIN
Insert statements...
END
END IF;
But this doesn't seem to be working for me. I have also taken a look at IF NOT EXISTS but that as well has not been working. The MERGE command I dont believe is relevant here because I am not pulling from a separate table, just hard-coded insert statements. I am using Oracle SQL developer, am I missing something?
SOLVED
This worked for me:
insert into table (col1, col2)
select 'val1','val2'
from dual
where not exists(select *
from table
where (col1 ="val1" and col2='val2'));
Something like this (I don't have oracle handy)
INSERT INTO TABLE (PK, COl2, Col3)
SELECT 1, 'X', 'Y' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM TABLE WHERE PK = 1);
The select only returns records of the record doesn't exist (matching on the PK column)
You can do one of those per record or you can do something like this:
INSERT INTO TABLE (PK, COl2, Col3)
SELECT 1, 'X', 'Y' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM TABLE WHERE PK = 1)
UNION ALL
SELECT 2, 'X', 'Y' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM TABLE WHERE PK = 2);
UNION ALL
SELECT 3, 'X', 'Y' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM TABLE WHERE PK = 3);
This is probably OK for half a dozen records (it can be generated from Excel formulas).
We cannot use SQL if an IF statement like this:
IF (SELECT COUNT(*) FROM foo WHERE x = bar) <= 0
So what you need to do is execute the count then test it
SELECT COUNT(*)
into v_count
FROM foo WHERE x = bar;
if v_count <= 0
THEN
BEGIN
Insert statements...
END;
END IF;

Two or more results of one CASE statement in SQL

Is it possible to SELECT value of two or more columns with one shot of CASE statement? I mean instead of:
select
ColumnA = case when CheckColumn='condition' then 'result1' end
,ColumnB = case when CheckColumn='condition' then 'result2' end
Something like:
select case when CheckColumn='condition' then ColumnA='result1', ColumnB='result2' end
UPDATE
Just the same as we can do with the UPDATE statement:
update CTE
set ColumnA='result1', ColumnB='result2'
where CheckColumn='condition'
It is not possible with CASE expression.
For every column you need new CASE
It is not possible, but you could use a table value constructor as a work around to this, to store each value for columna and columnb against your check column:
SELECT t.CheckColumn,
v.ColumnA,
v.ColumnB
FROM dbo.YourTable AS t
LEFT JOIN
(VALUES
('Condition1', 'Result1', 'Result2'),
('Condition2', 'Result3', 'Result4'),
('Condition3', 'Result5', 'Result6')
) AS v (CheckColumn, ColumnA, ColumnB)
ON v.CheckColumn = t.CheckColumn;
If you have more complex conditions, then you can still apply this logic, but just use a pseudo-result for the join:
SELECT t.CheckColumn,
v.ColumnA,
v.ColumnB
FROM dbo.YourTable AS t
LEFT JOIN
(VALUES
(1, 'Result1', 'Result2'),
(2, 'Result3', 'Result4'),
(3, 'Result5', 'Result6')
) AS v (ConditionID, ColumnA, ColumnB)
ON v.ConditionID = CASE WHEN <some long expression> THEN 1
WHEN <some other long expression> THEN 2
ELSE 3
END;
The equivalent select to the update is:
select 'result1', 'result2'
. . .
where CheckColumn = 'condition';
Your select is different because it produces NULL values. There is an arcane way you can essentially do this with outer apply:
select t2.*
from . . . outer apply
(select t.*
from (select 'result1' as col1, 'result2' as col2) t
where CheckColumn = 'condition'
) t2;
This will return NULL values when there is no match. And, you can have as many columns as you would like.
What I understood from your question is that you want to update multiple columns if certain condition is true.
For such situation you have to use MERGE statements.
Example of using MERGE is as given on msdn here.
Code example:
-- MERGE statement for update.
USE [Database Name];
GO
MERGE Inventory ity
USING Order ord
ON ity.ProductID = ord.ProductID
WHEN MATCHED THEN
UPDATE
SET ity.Quantity = ity.Quantity - ord.Quantity;
More MERGE statement example here.
You could solve this maybe with a CTE or a CROSS APPLY, somehting like
DECLARE #tbl2 TABLE(inx INT, val1 VARCHAR(10),val2 VARCHAR(10));
INSERT INTO #tbl2 VALUES(1,'value1a','value1b'),(2,'value2a','value2b'),(3,'value2a','value2b');
UPDATE yourTable SET col1=subTable.val1,col2=subTable.val2
FROM yourTable
CROSS APPLY(
SELECT val1,val2
FROM #tbl2
WHERE inx=1 --YourCondition
) AS subTable

What does this sql mean

INSERT INTO MAPPING_TBL ( G_ID, MR_ID, G_TYPE, G_NUMBER )
SELECT :G_ID AS G_ID, :MR_ID AS MR_ID, :G_TYPE AS G_TYPE, :G_NUMBER AS G_NUMBER
FROM DUAL WHERE NOT EXISTS
(SELECT G_ID, MR_ID, G_TYPE, G_NUMBER
FROM MAPPING_TBL
WHERE G_ID = :G_ID2 AND
MR_ID = :MR_ID2 AND
G_TYPE = :G_TYPE2 AND
G_NUMBER = :G_NUMBER2 )
Could anyone explain what does this sql actual doing? especially what does this
SELECT :G_ID AS G_ID, :MR_ID AS MR_ID, :G_TYPE AS G_TYPE, :G_NUMBER AS G_NUMBER
FROM DUAL
sql do, thanks.
This is a "conditional insert."
The statement is INSERTing a user-supplied record into a table MAPPING_TBL if that record does not already exist in the table. In MySQL this is accomplished as an 'INSERT IGNORE'. In contemporary Oracle one could use 'MERGE INTO' to the same effect.
The SELECT :G_ID AS G_ID ... FROM DUAL is a way of specifying a tuple of values, in this case parameterized values from the calling program. (If you for instance SELECTed 1, 2, 3, 4 FROM DUAL, you'd get those values back in a row. In this case, the calling program is supplying :G_ID and so on at query execution time.)
It is just a syntax of INSERT INTO...SELECT statement. To make it more simple, take this example below
INSERT INTO table1 (colA, colB, colC)
SELECT colA, colB, colC
FROM table2
What it does is, Whatever rows that are SELECTed from table2 will be INSERTed on table1.
See for more info: Oracle [INSERT INTO...SELECT]
SELECT :G_ID AS G_ID, :MR_ID AS MR_ID, :G_TYPE AS G_TYPE, :G_NUMBER AS G_NUMBER
FROM DUAL
The semi-colon means the user will be prompted to enter those values. They are like parameters that are expected to be filled in at run-time

How can I insert multiple rows into oracle with a sequence value?

I know that I can insert multiple rows using a single statement, if I use the syntax in this answer.
However, one of the values I am inserting is taken from a sequence, i.e.
insert into TABLE_NAME
(COL1,COL2)
select MY_SEQ.nextval,'some value' from dual
union all
select MY_SEQ.nextval,'another value' from dual
;
If I try to run it, I get an ORA-02287 error. Is there any way around this, or should I just use a lot of INSERT statements?
EDIT:
If I have to specify column names for all other columns other than the sequence, I lose the original brevity, so it's just not worth it. In that case I'll just use multiple INSERT statements.
This works:
insert into TABLE_NAME (COL1,COL2)
select my_seq.nextval, a
from
(SELECT 'SOME VALUE' as a FROM DUAL
UNION ALL
SELECT 'ANOTHER VALUE' FROM DUAL)
It does not work because sequence does not work in following scenarios:
In a WHERE clause
In a GROUP BY or ORDER BY clause
In a DISTINCT clause
Along with a UNION or INTERSECT or MINUS
In a sub-query
Source: http://www.orafaq.com/wiki/ORA-02287
However this does work:
insert into table_name
(col1, col2)
select my_seq.nextval, inner_view.*
from (select 'some value' someval
from dual
union all
select 'another value' someval
from dual) inner_view;
Try it out:
create table table_name(col1 varchar2(100), col2 varchar2(100));
create sequence vcert.my_seq
start with 1
increment by 1
minvalue 0;
select * from table_name;
insert into TABLE_NAME
(COL1,COL2)
WITH
data AS
(
select 'some value' x from dual
union all
select 'another value' x from dual
)
SELECT my_seq.NEXTVAL, x
FROM data
;
I think that is what you want, but i don't have access to oracle to test it right now.
From Oracle Wiki, error 02287 is
An ORA-02287 occurs when you use a sequence where it is not allowed.
Of the places where sequences can't be used, you seem to be trying:
In a sub-query
So it seems you can't do multiples in the same statement.
The solution they offer is:
If you want the sequence value to be inserted into the column
for every row created, then create a before insert trigger and
fetch the sequence value in the trigger and assign it to the column
A possibility is to create a trigger on insert to add in the correct sequence number.
this works and there is no need to use union all.
Insert into BARCODECHANGEHISTORY (IDENTIFIER,MESSAGETYPE,FORMERBARCODE,NEWBARCODE,REPLACEMENTDATETIME,OPERATORID,REASON)
select SEQ_BARCODECHANGEHISTORY.nextval, MESSAGETYPE, FORMERBARCODE, NEWBARCODE, REPLACEMENTDATETIME, OPERATORID, REASON
from (
SELECT
'BAR' MESSAGETYPE,
'1234567890' FORMERBARCODE,
'1234567899' NEWBARCODE,
to_timestamp('20/07/12','DD/MM/RR HH24:MI:SSXFF') REPLACEMENTDATETIME,
'PIMATD' OPERATORID,
'CORRECTION' REASON
FROM dual
);