What does this sql mean - sql

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

Related

Get different query back based on a condition in PostgreSQL

I'm having a hard time with sql and probably this will look stupid but it shows what I am trying to achieve.
SELECT
CASE WHEN ( ( SELECT 1 FROM table_1 WHERE = condition ) IS NULL ) THEN
SELECT 'No result'::varchar
ELSE
SELECT
val_1,
val_2,
val_3
FROM
table_1
END;
A null answer is not good in my situation, I can't just use the sub-query as the main. And even if I could that would still leave the question open if the two tables were NOT the same like:
SELECT
CASE WHEN ( ( SELECT 1 FROM table_1 WHERE = condition ) IS NULL ) THEN
SELECT 'No result'::varchar
ELSE
SELECT
val_1,
val_2,
val_3
FROM
table_2 --TABLE REPLACED!
END;
As CASE-WHEN only works for one column it would be horrifying to have 20 of them with the same condition. Any help is appreciated! Thanks!
So you want to SELECT the table_log and if the result is not NULL show it to the client and if it is NULL show a message?
I created a fake table for testing. What you are looking for is the last SELECT-statement:
DROP TABLE IF EXISTS table_log;
CREATE TEMP TABLE table_log (
id INTEGER
,log_info VARCHAR)
;
INSERT INTO table_log VALUES
(1, 'test_entry')
;
ANALYZE table_log;
SELECT
COALESCE(b.log_info, 'No changes done!') AS log_info
FROM
(SELECT 'Fake-Data') a
LEFT OUTER JOIN (SELECT * FROM table_log WHERE id = 1) b ON (1=1);
If the given id = 1, you get the result, if it is something else (because it is not in the test-table) the premade message is given.
Here is a link to the db<>fiddle.

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;

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

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'
)

What is the equivalent of the Oracle "Dual" table in MS SqlServer?

What is the equivalent of the Oracle "Dual" table in MS SqlServer?
This is my Select:
SELECT pCliente,
'xxx.x.xxx.xx' AS Servidor,
xxxx AS Extension,
xxxx AS Grupo,
xxxx AS Puerto
FROM DUAL;
In sql-server, there is no dual you can simply do
SELECT pCliente,
'xxx.x.xxx.xx' AS Servidor,
xxxx AS Extension,
xxxx AS Grupo,
xxxx AS Puerto
However, if your problem is because you transfered some code from Oracle which reference to dual you can re-create the table :
CREATE TABLE DUAL
(
DUMMY VARCHAR(1)
)
GO
INSERT INTO DUAL (DUMMY)
VALUES ('X')
GO
You don't need DUAL in MSSQLserver
in oracle
select 'sample' from dual
is equal to
SELECT 'sample'
in sql server
While you usually don't need a DUAL table in SQL Server as explained by Jean-François Savard, I have needed to emulate DUAL for syntactic reasons in the past. Here are three options:
Create a DUAL table or view
-- A table
SELECT 'X' AS DUMMY INTO DUAL;
-- A view
CREATE VIEW DUAL AS SELECT 'X' AS DUMMY;
Once created, you can use it just as in Oracle.
Use a common table expression or a derived table
If you just need DUAL for the scope of a single query, this might do as well:
-- Common table expression
WITH DUAL(DUMMY) AS (SELECT 'X')
SELECT * FROM DUAL
-- Derived table
SELECT *
FROM (
SELECT 'X'
) DUAL(DUMMY)
In SQL Server there is no dual table. If you want to put a WHERE clause, you can simple put it directly like this:
SELECT 123 WHERE 1<2
I think in MySQL and Oracle they need a FROM clause to use a WHERE clause.
SELECT 123 FROM DUAL WHERE 1<2
This could be of some help I guess, when you need to join some tables based on local variables and get the information from those tables:
Note: Local variables must have been
Select #XCode as 'XCode '
,#XID as 'XID '
,x.XName as 'XName '
,#YCode as 'YCode '
,#YID as 'YID '
,y.YName as 'YName '
From (Select 1 as tst) t
Inner join Xtab x on x.XID = #XID
Inner join Ytab y on y.YID = #YID
It's much simpler than that.
Use literal values to establish data types.
Put quotes around column names if they need special characters.
Skip the WHERE clause if you need 1 row of data:
SELECT 'XCode' AS XCode
,1 AS XID
,'XName' AS "X Name"
,'YCode' AS YCode
,getDate() AS YID
,'YName' AS "Your Name"
WHERE 1 = 0

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
);